Skip to content

Commit

Permalink
Retrieve paged requests (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
James Bond authored and Jbond312 committed Apr 14, 2019
1 parent 22bf122 commit 29c9d5a
Show file tree
Hide file tree
Showing 19 changed files with 325 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/PlexRequests.Core/IRequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace PlexRequests.Core
public interface IRequestService
{
Task<Request> GetRequestById(Guid id);

Task<Paged<Request>> GetPaged(string title, PlexMediaTypes? mediaType, bool? isApproved, Guid? userId, int? page,
int? pageSize);
Task<Request> GetExistingMovieRequest(AgentTypes agentType, string agentSourceId);
Task<List<Request>> GetExistingTvRequests(AgentTypes agentType, string agentSourceId);
Task Create(Request request);
Expand Down
5 changes: 5 additions & 0 deletions src/PlexRequests.Core/RequestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public async Task<Request> GetRequestById(Guid id)
return await _requestRepository.GetOne(x => x.Id == id);
}

public async Task<Paged<Request>> GetPaged(string title, PlexMediaTypes? mediaType, bool? isApproved, Guid? userId, int? page, int? pageSize)
{
return await _requestRepository.GetPaged(title, mediaType, isApproved, userId, page, pageSize);
}

public async Task<Request> GetExistingMovieRequest(AgentTypes agentType, string agentSourceId)
{
return await _requestRepository.GetOne(x =>
Expand Down
4 changes: 4 additions & 0 deletions src/PlexRequests.Store/IRequestRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using PlexRequests.Store.Enums;
using PlexRequests.Store.Models;

namespace PlexRequests.Store
Expand All @@ -10,6 +11,9 @@ public interface IRequestRepository
{
Task Create(Request request);
Task<List<Request>> GetMany(Expression<Func<Request, bool>> filter = null);

Task<Paged<Request>> GetPaged(string title, PlexMediaTypes? mediaType, bool? isApproved, Guid? userId, int? page,
int? pageSize);
Task<Request> GetOne(Expression<Func<Request, bool>> filter = null);
Task Delete(Guid id);
}
Expand Down
12 changes: 12 additions & 0 deletions src/PlexRequests.Store/Models/Paged.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;

namespace PlexRequests.Store.Models
{
public class Paged<T> where T : class
{
public int TotalPages { get; set; }
public int PageSize { get; set; }
public int Page { get; set; }
public List<T> Items { get; set; }
}
}
1 change: 1 addition & 0 deletions src/PlexRequests.Store/Models/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ public class Request
public bool IsApproved { get; set; }
public string ImagePath { get; set; }
public DateTime AirDate { get; set; }
public DateTime Created { get; set; }
}
}
59 changes: 58 additions & 1 deletion src/PlexRequests.Store/RequestRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Linq.Expressions;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using PlexRequests.Store.Enums;
using PlexRequests.Store.Models;

namespace PlexRequests.Store
Expand All @@ -23,7 +25,62 @@ public async Task<List<Request>> GetMany(Expression<Func<Request, bool>> filter
var cursor = await GetRequestsCursor(filter);
return await cursor.ToListAsync();
}


public async Task<Paged<Request>> GetPaged(string title, PlexMediaTypes? mediaType, bool? isApproved, Guid? userId, int? page, int? pageSize)
{
var query = Collection.AsQueryable();

if (!string.IsNullOrEmpty(title))
{
query = query.Where(x => x.Title.ToLower().Contains(title.ToLower()));
}

if (mediaType != null)
{
query = query.Where(x => x.MediaType == mediaType);
}

if (isApproved != null)
{
query = query.Where(x => x.IsApproved == isApproved);
}

if (userId != null)
{
query = query.Where(x => x.RequestedByUserId == userId);
}

if (page == null)
{
page = 1;
}

if (pageSize == null)
{
pageSize = 10;
}

var totalItems = await query.CountAsync();

var totalPages = (int)Math.Ceiling(totalItems / (double)pageSize);

page -= 1;

query = query.OrderByDescending(x => x.Created)
.Skip(pageSize.Value * page.Value)
.Take(pageSize.Value);

var items = await query.ToListAsync();

return new Paged<Request>
{
Page = page.Value + 1,
PageSize = pageSize.Value,
TotalPages = totalPages,
Items = items
};
}

public async Task<Request> GetOne(Expression<Func<Request, bool>> filter = null)
{
var cursor = await GetRequestsCursor(filter);
Expand Down
2 changes: 1 addition & 1 deletion src/PlexRequests.TheMovieDb/Models/MovieDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class MovieDetails
public List<ProductionCountry> Production_Countries { get; set; }
public string Release_Date { get; set; }
public int Revenue { get; set; }
public int Runtime { get; set; }
public int? Runtime { get; set; }
public List<SpokenLanguage> Spoken_Languages { get; set; }
public string Status { get; set; }
public string Tagline { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ private void ThenRequestIsCreated()
_createdRequest.Title.Should().Be(_movieDetails.Title);
_createdRequest.ImagePath.Should().Be(_movieDetails.Poster_Path);
_createdRequest.AirDate.Should().Be(DateTime.Parse(_movieDetails.Release_Date));
_createdRequest.Created.Should().BeCloseTo(DateTime.UtcNow, 500);
}

private void WhenCommandActionIsCreated()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ private void ThenRequestIsCreated(int expectedSeasonCount)
_createdRequest.Title.Should().Be(_tvDetails.Name);
_createdRequest.AirDate.Should().Be(DateTime.Parse(_tvDetails.First_Air_Date));
_createdRequest.ImagePath.Should().Be(_tvDetails.Poster_Path);
_createdRequest.Created.Should().BeCloseTo(DateTime.UtcNow, 500);

for (var i = 0; i < expectedSeasonCount; i++)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using AutoFixture;
using AutoMapper;
using FluentAssertions;
using NSubstitute;
using PlexRequests.Core;
using PlexRequests.Mapping;
using PlexRequests.Models.Requests;
using PlexRequests.Store.Enums;
using PlexRequests.Store.Models;
using TestStack.BDDfy;
using Xunit;

namespace PlexRequests.UnitTests.Models.Requests
{
public class GetPagedRequestQueryHandlerTests
{
private readonly GetPagedRequestQueryHandler _underTest;
private readonly IRequestService _requestService;
private readonly IClaimsPrincipalAccessor _claimsAccessor;

private readonly Fixture _fixture;

private GetPagedRequestQuery _query;
private Paged<Request> _pagedRequest;
private Func<Task<GetPagedRequestQueryResult>> _queryAction;
private Guid _currentUserId;

public GetPagedRequestQueryHandlerTests()
{
var mapperConfig = new MapperConfiguration(opts => { opts.AddProfile(new RequestProfile()); });
var mapper = mapperConfig.CreateMapper();

_requestService = Substitute.For<IRequestService>();
_claimsAccessor = Substitute.For<IClaimsPrincipalAccessor>();

_underTest = new GetPagedRequestQueryHandler(mapper, _requestService, _claimsAccessor);

_fixture = new Fixture();
}

[Fact]
private void Returns_Requests_From_Request_Service()
{
this.Given(x => x.GivenAQuery())
.Given(x => x.GivenManyRequests())
.When(x => x.WhenQueryActionIsCreated())
.Then(x => x.ThenQueryReturnsCorrectResponse())
.BDDfy();
}

[Fact]
private void Gets_Current_Users_UserId_If_Include_Users_Requests()
{
this.Given(x => x.GivenAQuery())
.Given(x => x.GivenCurrentUsersRequestsOnly())
.Given(x => x.GivenManyRequests())
.Given(x => x.GivenAUsersClaimAccessor())
.When(x => x.WhenQueryActionIsCreated())
.Then(x => x.ThenQueryReturnsCorrectResponse())
.Then(x => x.ThenCurrentUsersUserIdWasUsed())
.BDDfy();
}

private void GivenAQuery()
{
_query = _fixture.Create<GetPagedRequestQuery>();
}

private void GivenCurrentUsersRequestsOnly()
{
_query.IncludeCurrentUsersOnly = true;
}

private void GivenAUsersClaimAccessor()
{
_currentUserId = _fixture.Create<Guid>();
_claimsAccessor.UserId.Returns(_currentUserId);
}

private void GivenManyRequests()
{
_pagedRequest = _fixture.Create<Paged<Request>>();

_requestService.GetPaged(Arg.Any<string>(), Arg.Any<PlexMediaTypes?>(), Arg.Any<bool?>(), Arg.Any<Guid?>(),
Arg.Any<int?>(), Arg.Any<int?>()).Returns(_pagedRequest);
}

private void WhenQueryActionIsCreated()
{
_queryAction = async () => await _underTest.Handle(_query, CancellationToken.None);
}

private async Task ThenQueryReturnsCorrectResponse()
{
var result = await _queryAction();

result.Should().NotBeNull();
result.Items.Count.Should().Be(_pagedRequest.Items.Count);
result.Should().BeEquivalentTo(_pagedRequest, options => options.ExcludingMissingMembers());
}

private void ThenCurrentUsersUserIdWasUsed()
{
_requestService.Received().GetPaged(Arg.Any<string>(), Arg.Any<PlexMediaTypes?>(), Arg.Any<bool?>(), Arg.Is<Guid?>(_currentUserId),
Arg.Any<int?>(), Arg.Any<int?>());
}
}
}
21 changes: 21 additions & 0 deletions src/PlexRequests/Controllers/RequestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PlexRequests.Models.Requests;
using PlexRequests.Store.Enums;

namespace PlexRequests.Controllers
{
Expand Down Expand Up @@ -45,5 +46,25 @@ public async Task<ActionResult> DeleteRequest([FromRoute][Required] Guid id)

return Ok();
}

[HttpGet("")]
public async Task<ActionResult<GetPagedRequestQueryResult>> GetRequests([FromQuery] string title,
[FromQuery] PlexMediaTypes? mediaType, [FromQuery] bool? includeCurrentUsersOnly, [FromQuery] bool? isApproved,
[FromQuery] int? page, [FromQuery] int? pageSize)
{
var query = new GetPagedRequestQuery
{
Title = title,
MediaType = mediaType,
IncludeCurrentUsersOnly = includeCurrentUsersOnly,
IsApproved = isApproved,
Page = page,
PageSize = pageSize
};

var response = await _mediator.Send(query);

return Ok(response);
}
}
}
1 change: 1 addition & 0 deletions src/PlexRequests/Mapping/RequestProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class RequestProfile : Profile
{
public RequestProfile()
{
CreateMap<RequestViewModel, Request>();
CreateMap<RequestSeasonViewModel, RequestSeason>();
CreateMap<RequestEpisodeViewModel, RequestEpisode>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ private async Task CreateRequest(CreateMovieRequestCommand request, MovieDetails
RequestedByUserName = _claimsPrincipalAccessor.Username,
Title = movieDetail.Title,
AirDate = DateTime.Parse(movieDetail.Release_Date),
ImagePath = movieDetail.Poster_Path
ImagePath = movieDetail.Poster_Path,
Created = DateTime.UtcNow
};

await _requestService.Create(newRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ private async Task<TvDetails> GetTvDetails(int theMovieDbId)
RequestedByUserName = _claimsPrincipalAccessor.Username,
Title = tvDetails.Name,
AirDate = DateTime.Parse(tvDetails.First_Air_Date),
ImagePath = tvDetails.Poster_Path
ImagePath = tvDetails.Poster_Path,
Created = DateTime.UtcNow
};

await _requestService.Create(tvRequest);
Expand Down
15 changes: 15 additions & 0 deletions src/PlexRequests/Models/Requests/GetPagedRequestQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using MediatR;
using PlexRequests.Store.Enums;

namespace PlexRequests.Models.Requests
{
public class GetPagedRequestQuery : IRequest<GetPagedRequestQueryResult>
{
public string Title { get; set; }
public PlexMediaTypes? MediaType { get; set; }
public bool? IsApproved { get; set; }
public bool? IncludeCurrentUsersOnly { get; set; }
public int? Page { get; set; }
public int? PageSize { get; set; }
}
}
Loading

0 comments on commit 29c9d5a

Please sign in to comment.