using System.Collections.Generic; using System.Linq; using System.Security.Principal; using System.Threading.Tasks; using AutoFixture; using MockQueryable.Moq; using Moq; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; using Ombi.Core.Engine.Interfaces; using Ombi.Core.Models; using Ombi.Core.Rule.Interfaces; using Ombi.Core.Settings; using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Test.Common; namespace Ombi.Core.Tests.Engine { [TestFixture] public class VoteEngineTests { [SetUp] public void Setup() { F = new Fixture(); VoteRepository = new Mock>(); VoteSettings = new Mock>(); MusicRequestEngine = new Mock(); TvRequestEngine = new Mock(); MovieRequestEngine = new Mock(); MovieRequestEngine = new Mock(); User = new Mock(); User.Setup(x => x.Identity.Name).Returns("abc"); UserManager = MockHelper.MockUserManager(new List { new OmbiUser { Id = "abc", UserName = "abc", NormalizedUserName = "ABC" } }); Rule = new Mock(); Engine = new VoteEngine(VoteRepository.Object, User.Object, UserManager.Object, Rule.Object, VoteSettings.Object, MusicRequestEngine.Object, TvRequestEngine.Object, MovieRequestEngine.Object); F.Behaviors.OfType().ToList() .ForEach(b => F.Behaviors.Remove(b)); F.Behaviors.Add(new OmitOnRecursionBehavior()); } public Fixture F { get; set; } public VoteEngine Engine { get; set; } public Mock User { get; set; } public Mock UserManager { get; set; } public Mock Rule { get; set; } public Mock> VoteRepository { get; set; } public Mock> VoteSettings { get; set; } public Mock MusicRequestEngine { get; set; } public Mock TvRequestEngine { get; set; } public Mock MovieRequestEngine { get; set; } [TestCaseSource(nameof(VoteData))] public async Task Vote(VoteType type, RequestType request) { VoteSettings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new VoteSettings { Enabled = true, MovieVoteMax = 10 }); var votes = F.CreateMany().ToList(); VoteRepository.Setup(x => x.GetAll()).Returns(new EnumerableQuery(votes) .AsQueryable() .BuildMock().Object); var result = new VoteEngineResult(); if (type == VoteType.Downvote) { result = await Engine.DownVote(1, request); } else { result = await Engine.UpVote(1, request); } Assert.That(result.Result, Is.True); VoteRepository.Verify(x => x.Add(It.Is(c => c.UserId == "abc" && c.VoteType == type)), Times.Once); VoteRepository.Verify(x => x.Delete(It.IsAny()), Times.Never); MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never); } public static IEnumerable VoteData { get { yield return new TestCaseData(VoteType.Upvote, RequestType.Movie).SetName("Movie_Upvote"); yield return new TestCaseData(VoteType.Downvote, RequestType.Movie).SetName("Movie_Downvote"); yield return new TestCaseData(VoteType.Upvote, RequestType.TvShow).SetName("Tv_Upvote"); yield return new TestCaseData(VoteType.Downvote, RequestType.TvShow).SetName("Tv_Downvote"); } } [TestCaseSource(nameof(AttemptedTwiceData))] public async Task Attempted_Twice(VoteType type, RequestType request) { VoteSettings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new VoteSettings { Enabled = true, MovieVoteMax = 10 }); var votes = F.CreateMany().ToList(); votes.Add(new Votes { RequestId = 1, RequestType = RequestType.Movie, UserId = "abc", VoteType = type }); VoteRepository.Setup(x => x.GetAll()).Returns(new EnumerableQuery(votes) .AsQueryable() .BuildMock().Object); var result = new VoteEngineResult(); if (type == VoteType.Downvote) { result = await Engine.DownVote(1, request); } else { result = await Engine.UpVote(1, request); } Assert.That(result.Result, Is.False); VoteRepository.Verify(x => x.Delete(It.IsAny()), Times.Never); MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never); } public static IEnumerable AttemptedTwiceData { get { yield return new TestCaseData(VoteType.Upvote, RequestType.Movie).SetName("Upvote_Attemped_Twice_Movie"); yield return new TestCaseData(VoteType.Downvote, RequestType.Movie).SetName("Downvote_Attempted_Twice_Movie"); yield return new TestCaseData(VoteType.Upvote, RequestType.TvShow).SetName("Upvote_Attemped_Twice_Tv"); yield return new TestCaseData(VoteType.Downvote, RequestType.TvShow).SetName("Downvote_Attempted_Twice_Tv"); } } [TestCaseSource(nameof(VoteConvertData))] public async Task Downvote_Converted_To_Upvote(VoteType type, RequestType request) { VoteSettings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new VoteSettings { Enabled = true, MovieVoteMax = 10 }); var votes = F.CreateMany().ToList(); votes.Add(new Votes { RequestId = 1, RequestType = request, UserId = "abc", VoteType = type == VoteType.Upvote ? VoteType.Downvote : VoteType.Upvote }); VoteRepository.Setup(x => x.GetAll()).Returns(new EnumerableQuery(votes) .AsQueryable() .BuildMock().Object); var result = new VoteEngineResult(); if (type == VoteType.Downvote) { result = await Engine.DownVote(1, request); } else { result = await Engine.UpVote(1, request); } Assert.That(result.Result, Is.True); VoteRepository.Verify(x => x.Delete(It.IsAny()), Times.Once); VoteRepository.Verify(x => x.Add(It.Is(v => v.VoteType == type)), Times.Once); MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never); } public static IEnumerable VoteConvertData { get { yield return new TestCaseData(VoteType.Upvote, RequestType.Movie).SetName("Downvote_Converted_To_UpVote_Movie"); yield return new TestCaseData(VoteType.Downvote, RequestType.Movie).SetName("UpVote_Converted_To_DownVote_Movie"); yield return new TestCaseData(VoteType.Upvote, RequestType.TvShow).SetName("Downvote_Converted_To_UpVote_TvShow"); yield return new TestCaseData(VoteType.Downvote, RequestType.TvShow).SetName("UpVote_Converted_To_DownVote_TvShow"); } } [TestCaseSource(nameof(VotingDisabledData))] public async Task Voting_Disabled(RequestType type) { VoteSettings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new VoteSettings { Enabled = false, MovieVoteMax = 10 }); var result = await Engine.UpVote(1, type); Assert.That(result.Result, Is.True); VoteRepository.Verify(x => x.Add(It.IsAny()), Times.Never); } public static IEnumerable VotingDisabledData { get { yield return new TestCaseData(RequestType.Movie).SetName("Voting_Disabled_Movie"); yield return new TestCaseData(RequestType.TvShow).SetName("Voting_Disabled_TV"); } } } }