diff --git a/server.tests/integrationTests/CharactersControllerIntegrationTests.cs b/server.tests/integrationTests/CharactersControllerIntegrationTests.cs index 11ffbc5..9afc85a 100644 --- a/server.tests/integrationTests/CharactersControllerIntegrationTests.cs +++ b/server.tests/integrationTests/CharactersControllerIntegrationTests.cs @@ -1,15 +1,19 @@ using FluentAssertions; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Testing; using server.Models; +using System.Collections; +using System.Collections.Generic; using System.Net; using System.Text.Json; namespace server.tests.integrationTests { - public class CharactersControllerIntegrationTests + public class CharactersControllerIntegrationTests { private readonly HttpClient _client; private readonly JsonSerializerOptions _serializerOptions; + private readonly string _endpoint; public CharactersControllerIntegrationTests() { @@ -23,29 +27,133 @@ namespace server.tests.integrationTests { PropertyNameCaseInsensitive = true }; + + _endpoint = "/api/characters"; } [Fact] - public async Task GetCharacters_RetrieveAllCharacters_Returns200StatusCodeWithCharacters() + public async Task GetCharactersAsync_AllCharacters_Returns200StatusCodeWithCharacters() { - var response = await _client.GetAsync("/api/characters"); + var response = await _client.GetAsync(_endpoint); var data = await response.Content.ReadAsStreamAsync(); var characters = JsonSerializer.Deserialize>(data); response.StatusCode.Should().Be(HttpStatusCode.OK); - characters.Should().NotBeNull(); - characters.Should().HaveCountGreaterThan(0); response.Headers.Should().ContainKey("X-Rate-Limit-Limit"); response.Headers.Should().ContainKey("X-Rate-Limit-Remaining"); response.Headers.Should().ContainKey("X-Rate-Limit-Reset"); + + characters.Should().NotBeNull(); + characters.Should().BeOfType>(); + characters.Should().HaveCountGreaterThan(0); } - + [Fact] - public async Task GetCharacters_RetrieveSeasonOneCharacters_Returns200StatusCodeWithCharacters() + public async Task GetCharactersAsync_SeasonOneCharacters_Returns200StatusCodeWithCharacters() { - return; + var seasonValue = 1; + + var url = $"{_endpoint}?season={seasonValue}"; + + var response = await _client.GetAsync(url); + + var data = await response.Content.ReadAsStreamAsync(); + + var characters = JsonSerializer.Deserialize>(data, _serializerOptions); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + response.Headers.Should().ContainKey("X-Rate-Limit-Limit"); + response.Headers.Should().ContainKey("X-Rate-Limit-Remaining"); + response.Headers.Should().ContainKey("X-Rate-Limit-Reset"); + + characters.Should().NotBeNull(); + characters.Should().BeOfType>(); + characters.Should().HaveCountGreaterThan(0); + + foreach (var character in characters) + { + character.Seasons.Should().Contain(seasonValue); + } + } + + [Fact] + public async Task GetCharactersAsync_InvalidSeasonQueryParameter_Returns400StatusCodeWithValidationProblemDetails() + { + var seasonValue = "test"; + + var url = $"{_endpoint}?season={seasonValue}"; + + var response = await _client.GetAsync(url); + + var data = await response.Content.ReadAsStreamAsync(); + + var details = JsonSerializer.Deserialize(data, _serializerOptions); + + response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + response.Headers.Should().ContainKey("X-Rate-Limit-Limit"); + response.Headers.Should().ContainKey("X-Rate-Limit-Remaining"); + response.Headers.Should().ContainKey("X-Rate-Limit-Reset"); + + details.Should().NotBeNull(); + details.Should().BeOfType(); + } + + [Fact] + public async Task GetCharactersAsync_NameContainsJason_Returns200StatusCodeWithCharacters() + { + var nameValue = "jason"; + + var url = $"{_endpoint}?name={nameValue}"; + + var response = await _client.GetAsync(url); + + var data = await response.Content.ReadAsStreamAsync(); + + var characters = JsonSerializer.Deserialize>(data, _serializerOptions); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + response.Headers.Should().ContainKey("X-Rate-Limit-Limit"); + response.Headers.Should().ContainKey("X-Rate-Limit-Remaining"); + response.Headers.Should().ContainKey("X-Rate-Limit-Reset"); + + characters.Should().NotBeNull(); + characters.Should().BeOfType>(); + characters.Should().HaveCountGreaterThan(0); + + foreach (var character in characters) + { + character.FullName.ToLower().Should().Contain(nameValue); + } + } + + [Fact] + public async Task GetCharactersAsync_ActorNameContainsMandy_Returns200StatusCodeWithCharacters() + { + var actorNameValue = "mandy"; + + var url = $"{_endpoint}?actorname={actorNameValue}"; + + var response = await _client.GetAsync(url); + + var data = await response.Content.ReadAsStreamAsync(); + + var characters = JsonSerializer.Deserialize>(data, _serializerOptions); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + response.Headers.Should().ContainKey("X-Rate-Limit-Limit"); + response.Headers.Should().ContainKey("X-Rate-Limit-Remaining"); + response.Headers.Should().ContainKey("X-Rate-Limit-Reset"); + + characters.Should().NotBeNull(); + characters.Should().BeOfType>(); + characters.Should().HaveCountGreaterThan(0); + + foreach (var character in characters) + { + character.ActorFullName.ToLower().Should().Contain(actorNameValue); + } } } } diff --git a/server.tests/unitTests/CharacterControllerUnitTests.cs b/server.tests/unitTests/CharacterControllerUnitTests.cs index 9337729..929857c 100644 --- a/server.tests/unitTests/CharacterControllerUnitTests.cs +++ b/server.tests/unitTests/CharacterControllerUnitTests.cs @@ -1,6 +1,10 @@ -using Moq; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc; +using Moq; using server.Controllers.v1; +using server.Models; using server.Persistence.Repositories; +using System.Net; namespace server.tests.unitTests { @@ -14,5 +18,53 @@ namespace server.tests.unitTests _mockRepo = new Mock(); _controller = new CharactersController(_mockRepo.Object); } + + [Fact] + public async Task GetCharactersAsync_AllCharacters_Returns200StatusCodeWithCharactersCollection() + { + var filter = new CharacterFilter(); + + var characters = new List {new Character(), new Character()}; + + _mockRepo + .Setup(repo => repo.GetCharactersAsync(filter)) + .ReturnsAsync(characters); + + var response = await _controller.GetCharactersAsync(filter) as ObjectResult; + var data = response.Value as List; + + _mockRepo.Verify(repo => repo.GetCharactersAsync(It.IsAny()), Times.Once()); + + response.Should().NotBeNull(); + response.Should().BeOfType(); + response.StatusCode.Should().Be((int)HttpStatusCode.OK); + + data.Should().NotBeNull(); + data.Should().BeOfType>(); + data.Should().HaveCount(2); + } + + [Fact] + public async Task GetCharactersAsync_RepoThrowsException_Returns500StatusCodeWithProblemDetails() + { + var filter = new CharacterFilter(); + + _mockRepo + .Setup(repo => repo.GetCharactersAsync(filter)) + .Throws(new Exception()); + + var response = await _controller.GetCharactersAsync(filter) as ObjectResult; + + var details = response.Value; + + _mockRepo.Verify(repo => repo.GetCharactersAsync(It.IsAny()), Times.Once()); + + response.Should().NotBeNull(); + response.Should().BeOfType(); + response.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); + + details.Should().NotBeNull(); + details.Should().BeOfType(); + } } }