New Series Relation - Edition (#1583)

* Moved UpdateRelatedSeries from controller to SeriesService.cs

* Added 2 tests.
- UpdateRelatedSeries_ShouldDeletePrequelRelation
- UpdateRelatedSeries_ShouldNotAllowDuplicates

* Some docs and codestyle nitpicks

* Simplified tests and made easier to read

* Added 'Editions' series relation

* Missing code to properly show the relations in the UI

* Create Service for GetRelatedServices

* Added unit test. Assert Edition, Prequel and Sequel do not return parent while others do

* fixed missing userRating

* Add requested changes:
- Rename one test
- Split one test into two tests
This commit is contained in:
ThePromidius 2022-10-17 15:11:12 +02:00 committed by GitHub
parent 8e79c3b839
commit 7d65dc0530
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 364 additions and 72 deletions

View file

@ -5,12 +5,14 @@ using System.Linq;
using System.Threading.Tasks;
using API.Comparators;
using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.CollectionTags;
using API.DTOs.Metadata;
using API.DTOs.SeriesDetail;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
using API.Helpers;
using API.SignalR;
using Microsoft.AspNetCore.Mvc;
@ -25,7 +27,8 @@ public interface ISeriesService
Task<bool> UpdateSeriesMetadata(UpdateSeriesMetadataDto updateSeriesMetadataDto);
Task<bool> UpdateRating(AppUser user, UpdateSeriesRatingDto updateSeriesRatingDto);
Task<bool> DeleteMultipleSeries(IList<int> seriesIds);
Task<bool> UpdateRelatedSeries(UpdateRelatedSeriesDto dto);
Task<RelatedSeriesDto> GetRelatedSeries(int userId, int seriesId);
}
public class SeriesService : ISeriesService
@ -624,4 +627,76 @@ public class SeriesService : ISeriesService
_ => "Chapter"
};
}
/// <summary>
/// Returns all related series against the passed series Id
/// </summary>
/// <param name="userId"></param>
/// <param name="seriesId"></param>
/// <returns></returns>
public async Task<RelatedSeriesDto> GetRelatedSeries(int userId, int seriesId)
{
return await _unitOfWork.SeriesRepository.GetRelatedSeries(userId, seriesId);
}
/// <summary>
/// Update the relations attached to the Series. Does not generate associated Sequel/Prequel pairs on target series.
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<bool> UpdateRelatedSeries(UpdateRelatedSeriesDto dto)
{
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(dto.SeriesId, SeriesIncludes.Related);
UpdateRelationForKind(dto.Adaptations, series.Relations.Where(r => r.RelationKind == RelationKind.Adaptation).ToList(), series, RelationKind.Adaptation);
UpdateRelationForKind(dto.Characters, series.Relations.Where(r => r.RelationKind == RelationKind.Character).ToList(), series, RelationKind.Character);
UpdateRelationForKind(dto.Contains, series.Relations.Where(r => r.RelationKind == RelationKind.Contains).ToList(), series, RelationKind.Contains);
UpdateRelationForKind(dto.Others, series.Relations.Where(r => r.RelationKind == RelationKind.Other).ToList(), series, RelationKind.Other);
UpdateRelationForKind(dto.SideStories, series.Relations.Where(r => r.RelationKind == RelationKind.SideStory).ToList(), series, RelationKind.SideStory);
UpdateRelationForKind(dto.SpinOffs, series.Relations.Where(r => r.RelationKind == RelationKind.SpinOff).ToList(), series, RelationKind.SpinOff);
UpdateRelationForKind(dto.AlternativeSettings, series.Relations.Where(r => r.RelationKind == RelationKind.AlternativeSetting).ToList(), series, RelationKind.AlternativeSetting);
UpdateRelationForKind(dto.AlternativeVersions, series.Relations.Where(r => r.RelationKind == RelationKind.AlternativeVersion).ToList(), series, RelationKind.AlternativeVersion);
UpdateRelationForKind(dto.Doujinshis, series.Relations.Where(r => r.RelationKind == RelationKind.Doujinshi).ToList(), series, RelationKind.Doujinshi);
UpdateRelationForKind(dto.Prequels, series.Relations.Where(r => r.RelationKind == RelationKind.Prequel).ToList(), series, RelationKind.Prequel);
UpdateRelationForKind(dto.Sequels, series.Relations.Where(r => r.RelationKind == RelationKind.Sequel).ToList(), series, RelationKind.Sequel);
UpdateRelationForKind(dto.Editions, series.Relations.Where(r => r.RelationKind == RelationKind.Edition).ToList(), series, RelationKind.Edition);
if (!_unitOfWork.HasChanges()) return true;
return await _unitOfWork.CommitAsync();
}
/// <summary>
/// Applies the provided list to the series. Adds new relations and removes deleted relations.
/// </summary>
/// <param name="dtoTargetSeriesIds"></param>
/// <param name="adaptations"></param>
/// <param name="series"></param>
/// <param name="kind"></param>
private void UpdateRelationForKind(ICollection<int> dtoTargetSeriesIds, IEnumerable<SeriesRelation> adaptations, Series series, RelationKind kind)
{
foreach (var adaptation in adaptations.Where(adaptation => !dtoTargetSeriesIds.Contains(adaptation.TargetSeriesId)))
{
// If the seriesId isn't in dto, it means we've removed or reclassified
series.Relations.Remove(adaptation);
}
// At this point, we only have things to add
foreach (var targetSeriesId in dtoTargetSeriesIds)
{
// This ensures we don't allow any duplicates to be added
if (series.Relations.SingleOrDefault(r =>
r.RelationKind == kind && r.TargetSeriesId == targetSeriesId) !=
null) continue;
series.Relations.Add(new SeriesRelation()
{
Series = series,
SeriesId = series.Id,
TargetSeriesId = targetSeriesId,
RelationKind = kind
});
_unitOfWork.SeriesRepository.Update(series);
}
}
}