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.v1.UnitTests { public class EpisodesControllerUnitTests { private readonly Mock _mockRepo; private readonly EpisodesController _controller; public EpisodesControllerUnitTests() { _mockRepo = new Mock(); _controller = new EpisodesController(_mockRepo.Object); } [Fact] public async Task GetEpisodesAsync_AllEpisodes_Returns200StatusCodeWithEpisodesCollection() { var filter = new EpisodeFilter(); var episodes = new List { new Episode(), new Episode() }; _mockRepo .Setup(repo => repo.GetEpisodesAsync(filter)) .ReturnsAsync(episodes); var response = await _controller.GetEpisodesAsync(filter) as ObjectResult; var data = response.Value as List; _mockRepo.Verify(repo => repo.GetEpisodesAsync(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 GetEpisodesAsync_RepoThrowsException_Returns500StatusCodeWithProblemDetails() { var filter = new EpisodeFilter(); _mockRepo .Setup(repo => repo.GetEpisodesAsync(filter)) .Throws(new Exception()); var response = await _controller.GetEpisodesAsync(filter) as ObjectResult; var details = response.Value; _mockRepo.Verify(repo => repo.GetEpisodesAsync(It.IsAny()), Times.Once()); response.Should().NotBeNull(); response.Should().BeOfType(); response.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); details.Should().NotBeNull(); details.Should().BeOfType(); } [Fact] public async Task GetEpisodeByNumberAsync_ValidEpisodeNumber_Returns200StatusWithEpisode() { var episodeNumber = 1; _mockRepo .Setup(repo => repo.GetEpisodeByNumberAsync(episodeNumber)) .ReturnsAsync(new Episode()); var response = await _controller.GetEpisodeByNumberAsync(episodeNumber) as ObjectResult; var episode = response.Value; _mockRepo.Verify(repo => repo.GetEpisodeByNumberAsync(It.IsAny()), Times.Once()); response.Should().NotBeNull(); response.Should().BeOfType(); response.StatusCode.Should().Be((int)HttpStatusCode.OK); episode.Should().NotBeNull(); episode.Should().BeOfType(); } [Fact] public async Task GetEpisodeByNumberAsync_ValidEpisodeNumberForNonExistentEpisode_Returns404StatusWithProblemDetails() { var episodeNumber = 3000; _mockRepo .Setup(repo => repo.GetEpisodeByNumberAsync(episodeNumber)) .ReturnsAsync(null as Episode); var response = await _controller.GetEpisodeByNumberAsync(episodeNumber) as ObjectResult; var details = response.Value; _mockRepo.Verify(repo => repo.GetEpisodeByNumberAsync(It.IsAny()), Times.Once()); response.Should().NotBeNull(); response.Should().BeOfType(); response.StatusCode.Should().Be((int)HttpStatusCode.NotFound); details.Should().NotBeNull(); details.Should().BeOfType(); } [Fact] public async Task GetEpisodeByNumberAsync_RepoThrowsException_Returns500StatusCodeWithProblemDetails() { var episodeNumber = 1; _mockRepo .Setup(repo => repo.GetEpisodeByNumberAsync(episodeNumber)) .Throws(new Exception()); var response = await _controller.GetEpisodeByNumberAsync(episodeNumber) as ObjectResult; var details = response.Value; _mockRepo.Verify(repo => repo.GetEpisodeByNumberAsync(It.IsAny()), Times.Once()); response.Should().NotBeNull(); response.Should().BeOfType(); response.StatusCode.Should().Be((int)HttpStatusCode.InternalServerError); details.Should().NotBeNull(); details.Should().BeOfType(); } } }