Voting engine mostly done, adding tests for it !wip

pull/2556/head
TidusJar 6 years ago
parent 2181be30f5
commit b73bdec789

@ -0,0 +1,57 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using Ombi.Core.Authentication;
using Ombi.Core.Engine;
using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Settings;
using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.Tests.Engine
{
[TestFixture]
public class VoteEngineTests
{
[SetUp]
public void Setup()
{
VoteRepository = new Mock<IRepository<Votes>>();
VoteSettings = new Mock<ISettingsService<VoteSettings>>();
MusicRequestEngine = new Mock<IMusicRequestEngine>();
TvRequestEngine = new Mock<ITvRequestEngine>();
MovieRequestEngine = new Mock<IMovieRequestEngine>();
MovieRequestEngine = new Mock<IMovieRequestEngine>();
User = new Mock<IPrincipal>();
UserManager = new Mock<OmbiUserManager>();
Rule = new Mock<IRuleEvaluator>();
Engine = new VoteEngine(VoteRepository.Object, User.Object, UserManager.Object, Rule.Object, VoteSettings.Object, MusicRequestEngine.Object,
TvRequestEngine.Object, MovieRequestEngine.Object);
}
public VoteEngine Engine { get; set; }
public Mock<IPrincipal> User { get; set; }
public Mock<OmbiUserManager> UserManager { get; set; }
public Mock<IRuleEvaluator> Rule { get; set; }
public Mock<IRepository<Votes>> VoteRepository { get; set; }
public Mock<ISettingsService<VoteSettings>> VoteSettings { get; set; }
public Mock<IMusicRequestEngine> MusicRequestEngine { get; set; }
public Mock<ITvRequestEngine> TvRequestEngine { get; set; }
public Mock<IMovieRequestEngine> MovieRequestEngine { get; set; }
[Test]
public async Task New_Upvote()
{
var votes = new List<Votes>();
AutoFi
VoteRepository.Setup(x => x.GetAll()).Returns(new EnumerableQuery<Votes>())
var result = await Engine.UpVote(1, RequestType.Movie);
}
}
}

@ -6,91 +6,142 @@ using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Authentication;
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.Store.Repository.Requests;
namespace Ombi.Core.Engine
{
public class VoteEngine : BaseEngine
{
public VoteEngine(IRepository<Votes> votes, IPrincipal user, OmbiUserManager um, IRuleEvaluator r) : base(user, um, r)
public VoteEngine(IRepository<Votes> votes, IPrincipal user, OmbiUserManager um, IRuleEvaluator r, ISettingsService<VoteSettings> voteSettings,
IMusicRequestEngine musicRequestEngine, ITvRequestEngine tvRequestEngine, IMovieRequestEngine movieRequestEngine) : base(user, um, r)
{
_voteRepository = votes;
_voteSettings = voteSettings;
_movieRequestEngine = movieRequestEngine;
_musicRequestEngine = musicRequestEngine;
_tvRequestEngine = tvRequestEngine;
}
private readonly IRepository<Votes> _voteRepository;
private readonly ISettingsService<VoteSettings> _voteSettings;
private readonly IMusicRequestEngine _musicRequestEngine;
private readonly ITvRequestEngine _tvRequestEngine;
private readonly IMovieRequestEngine _movieRequestEngine;
public async Task<Votes> GetVotesForMovie(int requestId)
public IQueryable<Votes> GetVotes(int requestId, RequestType requestType)
{
return await _voteRepository.GetAll().FirstOrDefaultAsync(x => x.RequestType == RequestType.Movie && x.RequestId == requestId);
}
public IQueryable<Votes> GetVotesForMovie(IEnumerable<int> requestIds)
{
return _voteRepository.GetAll().Where(x => x.RequestType == RequestType.Movie && requestIds.Contains(x.RequestId));
return _voteRepository.GetAll().Where(x => x.RequestType == requestType && requestId == x.RequestId);
}
public async Task<Votes> GetVotesForTv(int requestId)
public Task<Votes> GetVoteForUser(int requestId, string userId)
{
return await _voteRepository.GetAll().FirstOrDefaultAsync(x => x.RequestType == RequestType.TvShow && x.RequestId == requestId);
return _voteRepository.GetAll().FirstOrDefaultAsync(x => x.RequestId == requestId && x.UserId == userId);
}
public IQueryable<Votes> GetVotesForTv(IEnumerable<int> requestIds)
public async Task<VoteEngineResult> UpVote(int requestId, RequestType requestType)
{
return _voteRepository.GetAll().Where(x => x.RequestType == RequestType.TvShow && requestIds.Contains(x.RequestId));
}
// How many votes does this have?!
var currentVotes = GetVotes(requestId, requestType);
var voteSettings = await _voteSettings.GetSettingsAsync();
public async Task UpvoteMovie(int requestId)
{
// Does this user have a downvote? If so we should revert it and make it an upvote
var user = await GetUser();
var currentVote = await GetVoteForUser(requestId, user.Id);
if (currentVote != null && currentVote.VoteType == VoteType.Upvote)
{
return new VoteEngineResult { ErrorMessage = "You have already voted!" };
}
await RemoveCurrentVote(currentVote);
await _voteRepository.Add(new Votes
{
Date = DateTime.UtcNow,
RequestId = requestId,
RequestType = RequestType.Movie,
RequestType = requestType,
UserId = user.Id,
VoteType = VoteType.Upvote
});
var upVotes = await currentVotes.Where(x => x.VoteType == VoteType.Upvote).CountAsync();
var downVotes = -(await currentVotes.Where(x => x.VoteType == VoteType.Downvote).CountAsync());
var totalVotes = upVotes + downVotes;
RequestEngineResult result = null;
switch (requestType)
{
case RequestType.TvShow:
if (totalVotes >= voteSettings.TvShowVoteMax)
{
result = await _tvRequestEngine.ApproveChildRequest(requestId);
}
break;
case RequestType.Movie:
if (totalVotes >= voteSettings.MovieVoteMax)
{
result = await _movieRequestEngine.ApproveMovieById(requestId);
}
break;
case RequestType.Album:
if (totalVotes >= voteSettings.MusicVoteMax)
{
result = await _musicRequestEngine.ApproveAlbumById(requestId);
}
break;
default:
throw new ArgumentOutOfRangeException(nameof(requestType), requestType, null);
}
if (result != null && !result.Result)
{
return new VoteEngineResult
{
ErrorMessage = "Voted succesfully but could not approve movie!"
};
}
return new VoteEngineResult
{
Result = true
};
}
public async Task DownvoteMovie(int requestId)
public async Task<VoteEngineResult> DownVote(int requestId, RequestType requestType)
{
var user = await GetUser();
var currentVote = await GetVoteForUser(requestId, user.Id);
if (currentVote != null && currentVote.VoteType == VoteType.Upvote)
{
return new VoteEngineResult { ErrorMessage = "You have already voted!" };
}
await RemoveCurrentVote(currentVote);
await _voteRepository.Add(new Votes
{
Date = DateTime.UtcNow,
RequestId = requestId,
RequestType = RequestType.Movie,
RequestType = requestType,
UserId = user.Id,
VoteType = VoteType.Downvote
});
}
public async Task UpvoteTv(int requestId)
{
var user = await GetUser();
await _voteRepository.Add(new Votes
return new VoteEngineResult
{
Date = DateTime.UtcNow,
RequestId = requestId,
RequestType = RequestType.TvShow,
UserId = user.Id,
VoteType = VoteType.Upvote
});
Result = true
};
}
public async Task DownvoteTv(int requestId)
public async Task RemoveCurrentVote(Votes currentVote)
{
var user = await GetUser();
await _voteRepository.Add(new Votes
if (currentVote != null)
{
Date = DateTime.UtcNow,
RequestId = requestId,
RequestType = RequestType.TvShow,
UserId = user.Id,
VoteType = VoteType.Downvote
});
await _voteRepository.Delete(currentVote);
}
}
}
}

@ -0,0 +1,10 @@
namespace Ombi.Core.Models
{
public class VoteEngineResult
{
public bool Result { get; set; }
public string Message { get; set; }
public bool IsError => !string.IsNullOrEmpty(ErrorMessage);
public string ErrorMessage { get; set; }
}
}

@ -0,0 +1,10 @@
namespace Ombi.Settings.Settings.Models
{
public class VoteSettings : Settings
{
public bool Enabled { get; set; }
public int MovieVoteMax { get; set; }
public int MusicVoteMax { get; set; }
public int TvShowVoteMax { get; set; }
}
}
Loading…
Cancel
Save