public void CalculateAdviseGroupRank_IfAdviseGroupContainsDeletedAdviseSets_ConsidersDeletedAdviseSetsForPlaybacksAge() { // Arrange var adviseGroupContent1 = new AdviseGroupContent("1", isFavorite: false); adviseGroupContent1.AddDisc(CreateTestDisc("1.1", new[] { CreateTestSong(11, RatingModel.R5, new DateTime(2021, 06, 26)) })); adviseGroupContent1.AddDisc(CreateTestDisc("1.2", new[] { CreateTestSong(12, RatingModel.R5, new DateTime(2021, 06, 28), isDeleted: true) })); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 5).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 27)))); var adviseGroupContent3 = CreateTestAdviseGroupContent("3", Enumerable.Range(6, 5).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2, adviseGroupContent3 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseGroupRank(adviseGroupContent1, playbacksInfo); // Assert // (discs number: 1 ^ 0.5) * (rating: 1.5 ^ 5) * (playbacks age: 1) rank.Should().Be(7.59375); }
public void CalculateAdviseSetRank_ForAdviseSetWithMixedRatings_ReturnsCorrectRank() { // Arrange var songs = new[] { CreateTestSong(11, rating: RatingModel.R2, new DateTime(2021, 06, 28)), CreateTestSong(12, rating: RatingModel.R3, new DateTime(2021, 06, 28)), CreateTestSong(13, rating: RatingModel.R5, new DateTime(2021, 06, 28)), CreateTestSong(14, rating: RatingModel.R4, new DateTime(2021, 06, 28)), }; var adviseGroupContent1 = CreateTestAdviseGroupContent("1", songs); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseSetRank(adviseGroupContent1.AdviseSets.Single(), playbacksInfo); // Assert // (rating: 1.5 ^ 2.5) * (playbacks age: 1) rank.Should().Be(4.133513940946613); }
public void CalculateSongRank_ForListenedSongWithRatingDefined_ReturnsCorrectRank() { // Arrange var song1 = CreateTestSong(11, RatingModel.R5, new DateTime(2021, 06, 26)); var song2 = CreateTestSong(12, RatingModel.R7, new DateTime(2021, 06, 27)); var song3 = CreateTestSong(13, RatingModel.R4, new DateTime(2021, 06, 28)); var adviseGroupContent1 = CreateTestAdviseGroupContent("1", new[] { song1, song2, song3 }); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank1 = target.CalculateSongRank(song1, playbacksInfo); var rank2 = target.CalculateSongRank(song2, playbacksInfo); var rank3 = target.CalculateSongRank(song3, playbacksInfo); // Assert // (rating: 1.5 ^ 5) * (playbacks age: 12) rank1.Should().Be(91.125); // (rating: 1.5 ^ 7) * (playbacks age: 11) rank2.Should().Be(187.9453125); // (rating: 1.5 ^ 4) * (playbacks age: 10) rank3.Should().Be(50.625); }
public void CalculateAdviseGroupRank_IfAdviseGroupContainsMultipleAdviseSets_ReturnsCorrectRank() { // Arrange var adviseGroupContent1 = new AdviseGroupContent("1", isFavorite: false); adviseGroupContent1.AddDisc(CreateTestDisc("1.1", new[] { CreateTestSong(11, RatingModel.R5, new DateTime(2021, 06, 26)) })); adviseGroupContent1.AddDisc(CreateTestDisc("1.2", new[] { CreateTestSong(12, RatingModel.R7, new DateTime(2021, 06, 27)) })); adviseGroupContent1.AddDisc(CreateTestDisc("1.3", new[] { CreateTestSong(13, RatingModel.R6, new DateTime(2021, 06, 28)) })); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseGroupRank(adviseGroupContent1, playbacksInfo); // Assert // (discs number: 3 ^ 0.5) * (rating: 1.5 ^ 6) * (playbacks age: 1) rank.Should().BeApproximately(19.729141, 0.000001); }
public void CalculateAdviseGroupRank_IfAdviseGroupContainsDeletedAdviseSets_SkipsDeletedAdviseSetsWhenCountingSetsNumberAndAverageRating() { // Arrange var adviseGroupContent1 = new AdviseGroupContent("1", isFavorite: false); adviseGroupContent1.AddDisc(CreateTestDisc("1.1", new[] { CreateTestSong(11, RatingModel.R5, new DateTime(2021, 06, 26)) })); adviseGroupContent1.AddDisc(CreateTestDisc("1.2", new[] { CreateTestSong(12, RatingModel.R3, new DateTime(2021, 06, 27)) })); adviseGroupContent1.AddDisc(CreateTestDisc("1.3", new[] { CreateTestSong(13, RatingModel.R6, new DateTime(2021, 06, 28), isDeleted: true) })); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseGroupRank(adviseGroupContent1, playbacksInfo); // Assert // (discs number: 2 ^ 0.5) * (rating: 1.5 ^ 6) * (playbacks age: 1) rank.Should().BeApproximately(7.15945616, 0.000001); }
public void CalculateAdviseGroupRank_ForAdviseGroupWithPlaybacksAndRatingsDefined_ReturnsCorrectRank() { // Arrange var adviseGroupContent1 = CreateTestAdviseGroupContent("1", new[] { CreateTestSong(11, RatingModel.R5, new DateTime(2021, 06, 26)) }); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", new[] { CreateTestSong(12, RatingModel.R7, new DateTime(2021, 06, 27)) }); var adviseGroupContent3 = CreateTestAdviseGroupContent("3", new[] { CreateTestSong(13, RatingModel.R4, new DateTime(2021, 06, 28)) }); var adviseGroupContent4 = CreateTestAdviseGroupContent("4", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2, adviseGroupContent3, adviseGroupContent4 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank1 = target.CalculateAdviseGroupRank(adviseGroupContent1, playbacksInfo); var rank2 = target.CalculateAdviseGroupRank(adviseGroupContent2, playbacksInfo); var rank3 = target.CalculateAdviseGroupRank(adviseGroupContent3, playbacksInfo); // Assert // (discs number: 1 ^ 0.5) * (rating: 1.5 ^ 5) * (playbacks age: 3) rank1.Should().Be(22.78125); // (discs number: 1 ^ 0.5) * (rating: 1.5 ^ 7) * (playbacks age: 2) rank2.Should().Be(34.171875); // (discs number: 1 ^ 0.5) * (rating: 1.5 ^ 4) * (playbacks age: 1) rank3.Should().Be(5.0625); }
public void CalculateAdviseSetRank_ForAdviseSetWithMultipleDiscs_ReturnsCorrectRank() { // Arrange var disc1 = CreateTestDisc("1.1", new[] { CreateTestSong(1, RatingModel.R5, new DateTime(2021, 08, 28)) }); var disc2 = CreateTestDisc("1.2", new[] { CreateTestSong(2, RatingModel.R7, new DateTime(2021, 08, 28)) }); var adviseSet = new AdviseSetModel { Id = new ItemId("1") }; disc1.AdviseSetInfo = new AdviseSetInfo(adviseSet, 1); disc2.AdviseSetInfo = new AdviseSetInfo(adviseSet, 2); var adviseGroupContent1 = new AdviseGroupContent("1", isFavorite: false); adviseGroupContent1.AddDisc(disc1); adviseGroupContent1.AddDisc(disc2); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(11, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 08, 27)))); var adviseGroupContent3 = CreateTestAdviseGroupContent("3", Enumerable.Range(21, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 08, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2, adviseGroupContent3 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseSetRank(adviseGroupContent1.AdviseSets.Single(), playbacksInfo); // Assert // (rating: 1.5 ^ 6) * (playbacks age: 1) rank.Should().Be(11.390625); }
public async Task Advise_SortsAdviseGroups() { // Arrange var adviseSet1 = CreateTestAdviseSet("1"); var adviseSet2 = CreateTestAdviseSet("2"); var adviseGroups = CreateAdviseGroups(adviseSet1, adviseSet2).ToList(); var playbacksInfo = new PlaybacksInfo(adviseGroups); var adviseContentSorterStub = new Mock <IAdviseContentSorter>(); adviseContentSorterStub.Setup(x => x.SortAdviseGroups(adviseGroups, playbacksInfo)).Returns(new[] { adviseGroups[1], adviseGroups[0] }); adviseContentSorterStub.Setup(x => x.SortAdviseSets(It.IsAny <IEnumerable <AdviseSetContent> >(), playbacksInfo)) .Returns <IEnumerable <AdviseSetContent>, PlaybacksInfo>((adviseSets, _) => adviseSets); var mocker = new AutoMocker(); mocker.Use(adviseContentSorterStub); var target = mocker.CreateInstance <RankBasedAdviser>(); // Act var advises = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedAdvises = new[] { AdvisedPlaylist.ForAdviseSet(adviseSet2), AdvisedPlaylist.ForAdviseSet(adviseSet1), }; advises.Should().BeEquivalentTo(expectedAdvises, x => x.WithStrictOrdering()); }
public async Task Advise_IfSongsAreAdvised_ReturnsSongsWithHigherRankFirst() { // Arrange var settings = new HighlyRatedSongsAdviserSettings { OneAdviseSongsNumber = 3, MaxTerms = new[] { new MaxRatingTerm { Rating = RatingModel.R10, Days = 30, }, }, }; var song1 = CreateTestSong(1, RatingModel.R10, new DateTime(2017, 02, 01)); var song2 = CreateTestSong(2, RatingModel.R10, new DateTime(2017, 02, 01)); var song3 = CreateTestSong(3, RatingModel.R10, new DateTime(2017, 02, 01)); var adviseSet = CreateTestAdviseSet("1", new[] { song1, song2, song3 }); var adviseGroups = CreateAdviseGroups(adviseSet); var playbacksInfo = new PlaybacksInfo(adviseGroups); var adviseRankCalculatorStub = new Mock <IAdviseRankCalculator>(); adviseRankCalculatorStub.Setup(x => x.CalculateSongRank(song1, playbacksInfo)).Returns(0.25); adviseRankCalculatorStub.Setup(x => x.CalculateSongRank(song2, playbacksInfo)).Returns(0.75); adviseRankCalculatorStub.Setup(x => x.CalculateSongRank(song3, playbacksInfo)).Returns(0.50); var clockStub = new Mock <IClock>(); clockStub.Setup(x => x.Now).Returns(new DateTime(2017, 10, 01)); var mocker = new AutoMocker(); mocker.Use(adviseRankCalculatorStub); mocker.Use(clockStub); mocker.Use(Options.Create(settings)); var target = mocker.CreateInstance <HighlyRatedSongsAdviser>(); // Act var advises = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedAdvises = new[] { AdvisedPlaylist.ForHighlyRatedSongs(new[] { song2, song3, song1 }), }; advises.Should().BeEquivalentTo(expectedAdvises, x => x.WithStrictOrdering()); }
public async Task Advise_IfAllAdviseSetsAreActive_AdvisesSetsInCorrectOrder() { // Arrange // Last playback time for each advise group: // // adviseGroup1: 3, 2 // adviseGroup2: null // adviseGroup3: null, 1 // // Expected order (order within advise group is provided by inner adviser and is not changed): // // adviseSet21, adviseSet11, adviseSet31 var adviseSet11 = CreateTestAdviseSet("11", new[] { CreateTestSong(1, new DateTime(2018, 08, 17)) }); var adviseSet12 = CreateTestAdviseSet("12", new[] { CreateTestSong(2, new DateTime(2018, 08, 18)) }); var adviseSet21 = CreateTestAdviseSet("21", new[] { CreateTestSong(3) }); var adviseSet31 = CreateTestAdviseSet("31", new[] { CreateTestSong(4) }); var adviseSet32 = CreateTestAdviseSet("32", new[] { CreateTestSong(5, new DateTime(2018, 08, 19)) }); var adviseGroups = new[] { CreateAdviseGroup("1", isFavorite: true, adviseSet11, adviseSet12), CreateAdviseGroup("2", isFavorite: true, adviseSet21), CreateAdviseGroup("3", isFavorite: true, adviseSet31, adviseSet32), }; var playbacksInfo = new PlaybacksInfo(adviseGroups); var rankBasedAdviserStub = new Mock <IPlaylistAdviser>(); rankBasedAdviserStub.Setup(x => x.Advise(adviseGroups, playbacksInfo, It.IsAny <CancellationToken>())).ReturnsAsync(CreatedAdvisedPlaylists(adviseGroups)); var mocker = new AutoMocker(); mocker.Use(rankBasedAdviserStub); var target = mocker.CreateInstance <FavoriteAdviseGroupsAdviser>(); // Act var advisedPlaylists = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedPlaylists = new[] { AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup(adviseSet21), AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup(adviseSet11), AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup(adviseSet31), }; advisedPlaylists.Should().BeEquivalentTo(expectedPlaylists, x => x.WithStrictOrdering()); }
public async Task Advise_IfTooMuchSongsAreAdvised_SplitsThemIntoSmallerPlaylists() { // Arrange var settings = new HighlyRatedSongsAdviserSettings { OneAdviseSongsNumber = 12, MaxTerms = new[] { new MaxRatingTerm { Rating = RatingModel.R10, Days = 30, }, }, }; var songs1 = Enumerable.Range(1, 12).Select(id => CreateTestSong(id, RatingModel.R10, lastPlaybackTime: null)).ToList(); var songs2 = Enumerable.Range(13, 12).Select(id => CreateTestSong(id, RatingModel.R10, lastPlaybackTime: null)).ToList(); var adviseGroups = CreateAdviseGroups(CreateTestAdviseSet("1", songs1), CreateTestAdviseSet("2", songs2)); var playbacksInfo = new PlaybacksInfo(adviseGroups); var clockStub = new Mock <IClock>(); clockStub.Setup(x => x.Now).Returns(new DateTime(2017, 10, 01)); var mocker = new AutoMocker(); mocker.Use(clockStub); mocker.Use(Options.Create(settings)); var target = mocker.CreateInstance <HighlyRatedSongsAdviser>(); // Act var advises = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedAdvises = new[] { AdvisedPlaylist.ForHighlyRatedSongs(songs1), AdvisedPlaylist.ForHighlyRatedSongs(songs2), }; advises.Should().BeEquivalentTo(expectedAdvises, x => x.WithStrictOrdering()); }
public async Task Advise_ReturnsSongsWithHighRatingListenedEarlierThanConfiguredTerm() { // Arrange var settings = new HighlyRatedSongsAdviserSettings { OneAdviseSongsNumber = 12, MaxTerms = new[] { new MaxRatingTerm { Rating = RatingModel.R10, Days = 30, }, }, }; var songs = Enumerable.Range(1, 12).Select(id => CreateTestSong(id, RatingModel.R10, new DateTime(2017, 09, 01))).ToList(); var adviseSet = CreateTestAdviseSet("1", songs); var adviseGroups = CreateAdviseGroups(adviseSet); var playbacksInfo = new PlaybacksInfo(adviseGroups); var clockStub = new Mock <IClock>(); clockStub.Setup(x => x.Now).Returns(new DateTime(2017, 10, 07)); var mocker = new AutoMocker(); mocker.Use(clockStub); mocker.Use(Options.Create(settings)); var target = mocker.CreateInstance <HighlyRatedSongsAdviser>(); // Act var advises = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedAdvises = new[] { AdvisedPlaylist.ForHighlyRatedSongs(songs), }; advises.Should().BeEquivalentTo(expectedAdvises, x => x.WithStrictOrdering()); }
public async Task <IReadOnlyCollection <AdvisedPlaylist> > Advise(IEnumerable <DiscModel> discs, int requiredAdvisesCount, CancellationToken cancellationToken) { Memo ??= await sessionDataService.GetData <PlaylistAdviserMemo>(PlaylistAdviserDataKey, cancellationToken) ?? CreateDefaultMemo(); var playbacksMemo = Memo; var adviseGroups = (await discGrouper.GroupLibraryDiscs(discs, cancellationToken)).ToList(); var playbacksInfo = new PlaybacksInfo(adviseGroups); var highlyRatedSongsAdvises = await highlyRatedSongsAdviser.Advise(adviseGroups, playbacksInfo, cancellationToken); var favoriteAdviseGroupAdvises = await favoriteAdviseGroupsAdviser.Advise(adviseGroups, playbacksInfo, cancellationToken); var rankedAdvises = await rankBasedAdviser.Advise(adviseGroups, playbacksInfo, cancellationToken); var playlistQueue = new CompositeAdvisedPlaylistQueue(highlyRatedSongsAdvises, favoriteAdviseGroupAdvises, rankedAdvises); var advisedPlaylists = new List <AdvisedPlaylist>(requiredAdvisesCount); var knownAdviseSets = new HashSet <string>(); while (advisedPlaylists.Count < requiredAdvisesCount) { var currentAdvise = GetNextAdvisedPlaylist(playbacksMemo, playlistQueue); if (currentAdvise == null) { break; } var adviseSet = currentAdvise.AdviseSet; if (adviseSet != null) { if (knownAdviseSets.Contains(adviseSet.Id)) { continue; } knownAdviseSets.Add(adviseSet.Id); } advisedPlaylists.Add(currentAdvise); playbacksMemo = playbacksMemo.RegisterPlayback(currentAdvise); } return(advisedPlaylists); }
public void CalculateAdviseSetRank_ForAdviseSetWithoutPlaybacks_ReturnsMaxRank() { // Arrange var adviseGroupContent1 = CreateTestAdviseGroupContent("1", new[] { CreateTestSong(11, lastPlaybackTime: null) }); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseSetRank(adviseGroupContent1.AdviseSets.Single(), playbacksInfo); // Assert rank.Should().Be(Double.MaxValue); }
public async Task Advise_IfSomeAdviseSetsAreDeleted_SkipsDeletedAdviseSets() { // Arrange var deletedDisc = CreateTestDisc("1", isDeleted: true); var activeDisc = CreateTestDisc("2", isDeleted: false); var adviseGroup = new AdviseGroupContent("1", isFavorite: false); adviseGroup.AddDisc(deletedDisc); adviseGroup.AddDisc(activeDisc); var adviseGroups = new[] { adviseGroup }; var playbacksInfo = new PlaybacksInfo(adviseGroups); var adviseContentSorterStub = new Mock <IAdviseContentSorter>(); adviseContentSorterStub.Setup(x => x.SortAdviseGroups(It.IsAny <IEnumerable <AdviseGroupContent> >(), playbacksInfo)) .Returns <IEnumerable <AdviseGroupContent>, PlaybacksInfo>((adviseGroups, _) => adviseGroups); adviseContentSorterStub.Setup(x => x.SortAdviseSets(It.IsAny <IEnumerable <AdviseSetContent> >(), playbacksInfo)) .Returns <IEnumerable <AdviseSetContent>, PlaybacksInfo>((adviseSets, _) => adviseSets); var mocker = new AutoMocker(); mocker.Use(adviseContentSorterStub); var target = mocker.CreateInstance <RankBasedAdviser>(); // Act var advises = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedAdvises = new[] { AdvisedPlaylist.ForAdviseSet(activeDisc.ToAdviseSet()), }; advises.Should().BeEquivalentTo(expectedAdvises, x => x.WithStrictOrdering()); }
public async Task Advise_IfNumberOfAdvisedSongsIsNotEnough_ReturnsNoPlaylists() { // Arrange var settings = new HighlyRatedSongsAdviserSettings { OneAdviseSongsNumber = 12, MaxTerms = new[] { new MaxRatingTerm { Rating = RatingModel.R10, Days = 30, }, }, }; var songs = Enumerable.Range(1, 11).Select(id => CreateTestSong(id, RatingModel.R10, lastPlaybackTime: null)).ToList(); var adviseSet = CreateTestAdviseSet("1", songs); var adviseGroups = CreateAdviseGroups(adviseSet); var playbacksInfo = new PlaybacksInfo(adviseGroups); var clockStub = new Mock <IClock>(); clockStub.Setup(x => x.Now).Returns(new DateTime(2017, 10, 01)); var mocker = new AutoMocker(); mocker.Use(clockStub); mocker.Use(Options.Create(settings)); var target = mocker.CreateInstance <HighlyRatedSongsAdviser>(); // Act var advises = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert advises.Should().BeEmpty(); }
public void CalculateAdviseSetRank_ForListenedAdviseSetWithNoRatingDefined_ReturnsCorrectRank() { // Arrange var adviseGroupContent1 = CreateTestAdviseGroupContent("1", new[] { CreateTestSong(11, rating: null, new DateTime(2021, 06, 28)) }); var adviseGroupContent2 = CreateTestAdviseGroupContent("2", Enumerable.Range(1, 10).Select(id => CreateTestSong(id, RatingModel.R5, new DateTime(2021, 06, 29)))); var playbacksInfo = new PlaybacksInfo(new[] { adviseGroupContent1, adviseGroupContent2 }); var mocker = new AutoMocker(); var target = mocker.CreateInstance <AdviseRankCalculator>(); // Act var rank = target.CalculateAdviseSetRank(adviseGroupContent1.AdviseSets.Single(), playbacksInfo); // Assert // (rating: 1.5 ^ 5) * (playbacks age: 1) rank.Should().Be(7.59375); }
public async Task Advise_AdvisesOnlySetsFromFavoriteAdviseGroups() { // Arrange var adviseSetFromFavoriteAdviseGroup = CreateTestAdviseSet("1", new[] { CreateTestSong(1) }); var adviseSetFromNonFavoriteAdviseGroup = CreateTestAdviseSet("2", new[] { CreateTestSong(2) }); var adviseGroups = new[] { CreateAdviseGroup("1", isFavorite: false, adviseSetFromNonFavoriteAdviseGroup), CreateAdviseGroup("2", isFavorite: true, adviseSetFromFavoriteAdviseGroup), }; var playbacksInfo = new PlaybacksInfo(adviseGroups); var rankBasedAdviserStub = new Mock <IPlaylistAdviser>(); rankBasedAdviserStub.Setup(x => x.Advise(adviseGroups, playbacksInfo, It.IsAny <CancellationToken>())) .ReturnsAsync(CreatedAdvisedPlaylists(adviseGroups)); var mocker = new AutoMocker(); mocker.Use(rankBasedAdviserStub); var target = mocker.CreateInstance <FavoriteAdviseGroupsAdviser>(); // Act var advisedPlaylists = await target.Advise(adviseGroups, playbacksInfo, CancellationToken.None); // Assert var expectedPlaylists = new[] { AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup(adviseSetFromFavoriteAdviseGroup), }; advisedPlaylists.Should().BeEquivalentTo(expectedPlaylists, x => x.WithStrictOrdering()); }
public void SortAdviseSets_SortsAdviseSetsByTheirRank() { // Arrange var adviseSet1 = CreateTestAdviseSet("1"); var adviseSet2 = CreateTestAdviseSet("2"); var adviseSet3 = CreateTestAdviseSet("3"); var playbacksInfo = new PlaybacksInfo(Enumerable.Empty <AdviseGroupContent>()); var adviseRankCalculatorStub = new Mock <IAdviseRankCalculator>(); adviseRankCalculatorStub.Setup(x => x.CalculateAdviseSetRank(adviseSet1, playbacksInfo)).Returns(0.25); adviseRankCalculatorStub.Setup(x => x.CalculateAdviseSetRank(adviseSet2, playbacksInfo)).Returns(0.75); adviseRankCalculatorStub.Setup(x => x.CalculateAdviseSetRank(adviseSet3, playbacksInfo)).Returns(0.50); var mocker = new AutoMocker(); mocker.Use(adviseRankCalculatorStub); var target = mocker.CreateInstance <RankBasedAdviseContentSorter>(); // Act var result = target.SortAdviseSets(new[] { adviseSet1, adviseSet2, adviseSet3, }, playbacksInfo).ToList(); // Assert var expectedAdviseSets = new[] { adviseSet2, adviseSet3, adviseSet1, }; result.Should().BeEquivalentTo(expectedAdviseSets, x => x.WithStrictOrdering()); }
public void SortAdviseGroups_SortsAdviseGroupsByTheirRank() { // Arrange var adviseGroup1 = new AdviseGroupContent("group1", isFavorite: false); var adviseGroup2 = new AdviseGroupContent("group2", isFavorite: false); var adviseGroup3 = new AdviseGroupContent("group3", isFavorite: false); var playbacksInfo = new PlaybacksInfo(Enumerable.Empty <AdviseGroupContent>()); var adviseRankCalculatorStub = new Mock <IAdviseRankCalculator>(); adviseRankCalculatorStub.Setup(x => x.CalculateAdviseGroupRank(adviseGroup1, playbacksInfo)).Returns(0.25); adviseRankCalculatorStub.Setup(x => x.CalculateAdviseGroupRank(adviseGroup2, playbacksInfo)).Returns(0.75); adviseRankCalculatorStub.Setup(x => x.CalculateAdviseGroupRank(adviseGroup3, playbacksInfo)).Returns(0.50); var mocker = new AutoMocker(); mocker.Use(adviseRankCalculatorStub); var target = mocker.CreateInstance <RankBasedAdviseContentSorter>(); // Act var result = target.SortAdviseGroups(new[] { adviseGroup1, adviseGroup2, adviseGroup3 }, playbacksInfo).ToList(); // Assert var expectedAdviseGroups = new[] { adviseGroup2, adviseGroup3, adviseGroup1, }; result.Should().BeEquivalentTo(expectedAdviseGroups, x => x.WithStrictOrdering()); }
public Task <IReadOnlyCollection <AdvisedPlaylist> > Advise(IEnumerable <AdviseGroupContent> adviseGroups, PlaybacksInfo playbacksInfo, CancellationToken cancellationToken) { var songsToAdvise = adviseGroups .SelectMany(adviseGroup => adviseGroup.AdviseSets) .SelectMany(adviseSet => adviseSet.Discs) .SelectMany(disc => disc.ActiveSongs) .Where(IsTimeToListenHighlyRatedSong) .OrderByDescending(song => adviseRankCalculator.CalculateSongRank(song, playbacksInfo)) .ThenByDescending(song => song.GetRatingOrDefault()) .ToList(); var playlists = SplitSongsToPlaylists(songsToAdvise).ToList(); return(Task.FromResult <IReadOnlyCollection <AdvisedPlaylist> >(playlists)); }
private IEnumerable <AdviseSetContent> GetSortedAdviseSets(IEnumerable <AdviseGroupContent> adviseGroups, PlaybacksInfo playbacksInfo) { var activeAdviseGroups = adviseGroups.Where(x => !x.IsDeleted); foreach (var adviseGroup in adviseContentSorter.SortAdviseGroups(activeAdviseGroups, playbacksInfo)) { var activeAdviseSets = adviseGroup.AdviseSets.Where(x => !x.IsDeleted); yield return(adviseContentSorter.SortAdviseSets(activeAdviseSets, playbacksInfo).First()); } }
public Task <IReadOnlyCollection <AdvisedPlaylist> > Advise(IEnumerable <AdviseGroupContent> adviseGroups, PlaybacksInfo playbacksInfo, CancellationToken cancellationToken) { var playlists = GetSortedAdviseSets(adviseGroups, playbacksInfo) .Select(AdvisedPlaylist.ForAdviseSet) .ToList(); return(Task.FromResult <IReadOnlyCollection <AdvisedPlaylist> >(playlists)); }
public async Task <IReadOnlyCollection <AdvisedPlaylist> > Advise(IEnumerable <AdviseGroupContent> adviseGroups, PlaybacksInfo playbacksInfo, CancellationToken cancellationToken) { var adviseGroupsList = adviseGroups.ToList(); var adviseSetToAdviseGroupMap = adviseGroupsList .SelectMany(adviseGroup => adviseGroup.AdviseSets.Select(adviseSet => (adviseGroup, adviseSet))) .ToDictionary(x => x.adviseSet.Id, x => x.adviseGroup); var advisedPlaylists = await rankBasedAdviser.Advise(adviseGroupsList, playbacksInfo, cancellationToken); return(advisedPlaylists.Select(x => x.AdviseSet) .GroupBy(x => adviseSetToAdviseGroupMap[x.Id], new AdviseGroupContentEqualityComparer()) .Where(g => g.Key.IsFavorite) .OrderByDescending(g => playbacksInfo.GetPlaybacksPassed(g.Key)) .Select(g => g.First()) .Select(AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup) .ToList()); }