private IEnumerable <AdvisedPlaylist> SplitSongsToPlaylists(IReadOnlyCollection <SongModel> songs)
 {
     for (var i = 0; i + settings.OneAdviseSongsNumber <= songs.Count; i += settings.OneAdviseSongsNumber)
     {
         yield return(AdvisedPlaylist.ForHighlyRatedSongs(songs.Skip(i).Take(settings.OneAdviseSongsNumber)));
     }
 }
        public async Task Advise_MixesDifferentAdviseTypesCorrectly()
        {
            // Arrange

            var highlyRatedSongsAdvise1 = AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>());
            var highlyRatedSongsAdvise2 = AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>());

            var favoriteAdviseGroupAdvise1 = AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup(CreateTestAdviseSet(101));
            var favoriteAdviseGroupAdvise2 = AdvisedPlaylist.ForAdviseSetFromFavoriteAdviseGroup(CreateTestAdviseSet(102));

            var rankedBasedAdvises = Enumerable.Range(1, 10).Select(i => AdvisedPlaylist.ForAdviseSet(CreateTestAdviseSet(i))).ToList();

            var rankBasedAdviserStub = new Mock <IPlaylistAdviser>();

            rankBasedAdviserStub.Setup(x => x.Advise(It.IsAny <IEnumerable <AdviseGroupContent> >(), It.IsAny <PlaybacksInfo>(), It.IsAny <CancellationToken>())).ReturnsAsync(rankedBasedAdvises);

            var highlyRatedSongsAdviserStub = new Mock <IPlaylistAdviser>();

            highlyRatedSongsAdviserStub.Setup(x => x.Advise(It.IsAny <IEnumerable <AdviseGroupContent> >(), It.IsAny <PlaybacksInfo>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new[] { highlyRatedSongsAdvise1, highlyRatedSongsAdvise2 });

            var favoriteAdviseGroupsAdviserStub = new Mock <IPlaylistAdviser>();

            favoriteAdviseGroupsAdviserStub.Setup(x => x.Advise(It.IsAny <IEnumerable <AdviseGroupContent> >(), It.IsAny <PlaybacksInfo>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new[] { favoriteAdviseGroupAdvise1, favoriteAdviseGroupAdvise2 });

            var settings = new AdviserSettings
            {
                PlaybacksBetweenFavoriteAdviseGroups = 5,
                HighlyRatedSongsAdviser = new HighlyRatedSongsAdviserSettings
                {
                    PlaybacksBetweenHighlyRatedSongs = 10,
                },
            };

            var target = new CompositePlaylistAdviser(StubDiscGrouper(), rankBasedAdviserStub.Object, highlyRatedSongsAdviserStub.Object,
                                                      favoriteAdviseGroupsAdviserStub.Object, Mock.Of <ISessionDataService>(), Options.Create(settings));

            // Act

            var advises = (await target.Advise(Enumerable.Empty <DiscModel>(), 30, CancellationToken.None)).ToList();

            // Assert

            var expectedAdvises = new[]
            {
                highlyRatedSongsAdvise1,
                favoriteAdviseGroupAdvise1,
                rankedBasedAdvises[0], rankedBasedAdvises[1], rankedBasedAdvises[2], rankedBasedAdvises[3],
                favoriteAdviseGroupAdvise2,
                rankedBasedAdvises[4], rankedBasedAdvises[5], rankedBasedAdvises[6],
                highlyRatedSongsAdvise2,
                rankedBasedAdvises[7], rankedBasedAdvises[8], rankedBasedAdvises[9],
            };

            advises.Should().BeEquivalentTo(expectedAdvises);
        }
        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());
        }
예제 #4
0
        public void ForHighlyRatedSongs_DoesNotFillAdviseSet()
        {
            // Arrange

            // Act

            var target = AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>());

            // Assert

            target.AdviseSet.Should().BeNull();
        }
예제 #5
0
        public void ForHighlyRatedSongs_FillsTitleCorrectly()
        {
            // Arrange

            // Act

            var target = AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>());

            // Assert

            target.Title.Should().Be("Highly Rated Songs");
        }
예제 #6
0
        public void ForHighlyRatedSongs_FillsSongsCorrectly()
        {
            // Arrange

            var song1 = new SongModel();
            var song2 = new SongModel();

            // Act

            var target = AdvisedPlaylist.ForHighlyRatedSongs(new[] { song1, song2 });

            // Assert

            target.Songs.Should().BeEquivalentTo(new[] { song1, song2 }, x => x.WithStrictOrdering());
        }
예제 #7
0
        public void RegisterPlayback_IfPlaybackAdviseIsHighlyRatedSongs_SetsPlaybacksSinceHighlyRatedSongsPlaylistToZero()
        {
            // Arrange

            var target = new PlaylistAdviserMemo(playbacksSinceHighlyRatedSongsPlaylist: 3, playbacksSinceFavoriteAdviseGroup: 5);

            // Act

            var newMemo = target.RegisterPlayback(AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>()));

            // Assert

            var expectedMemo = new PlaylistAdviserMemo(playbacksSinceHighlyRatedSongsPlaylist: 0, playbacksSinceFavoriteAdviseGroup: 6);

            newMemo.Should().BeEquivalentTo(expectedMemo);
        }
        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 Advise_IfPlaylistAdviserMemoIsLoaded_UsesPreviousPlaybacksSinceHighlyRatedSongs()
        {
            // Arrange

            var settings = new AdviserSettings
            {
                HighlyRatedSongsAdviser = new HighlyRatedSongsAdviserSettings
                {
                    PlaybacksBetweenHighlyRatedSongs = 10,
                },
            };

            var highlyRatedSongsAdvise1 = AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>());
            var highlyRatedSongsAdvise2 = AdvisedPlaylist.ForHighlyRatedSongs(Enumerable.Empty <SongModel>());

            var rankBasedAdviserStub = new Mock <IPlaylistAdviser>();

            rankBasedAdviserStub.Setup(x => x.Advise(It.IsAny <IEnumerable <AdviseGroupContent> >(), It.IsAny <PlaybacksInfo>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(Enumerable.Range(0, 100).Select(i => AdvisedPlaylist.ForAdviseSet(CreateTestAdviseSet(i))).ToList());

            var highlyRatedSongsAdviserStub = new Mock <IPlaylistAdviser>();

            highlyRatedSongsAdviserStub.Setup(x => x.Advise(It.IsAny <IEnumerable <AdviseGroupContent> >(), It.IsAny <PlaybacksInfo>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new[] { highlyRatedSongsAdvise1, highlyRatedSongsAdvise2 });

            var sessionDataServiceStub = new Mock <ISessionDataService>();

            sessionDataServiceStub.Setup(x => x.GetData <PlaylistAdviserMemo>("PlaylistAdviserData", CancellationToken.None))
            .ReturnsAsync(new PlaylistAdviserMemo(playbacksSinceHighlyRatedSongsPlaylist: 2, playbacksSinceFavoriteAdviseGroup: 0));

            var target = new CompositePlaylistAdviser(StubDiscGrouper(), rankBasedAdviserStub.Object, highlyRatedSongsAdviserStub.Object,
                                                      StubEmptyPlaylistAdviser(), sessionDataServiceStub.Object, Options.Create(settings));

            // Act

            var advises = (await target.Advise(Enumerable.Empty <DiscModel>(), 30, CancellationToken.None)).ToList();

            // Assert

            advises.Where(x => x.AdvisedPlaylistType == AdvisedPlaylistType.HighlyRatedSongs).Should().HaveCount(2);
            advises[7].Should().BeSameAs(highlyRatedSongsAdvise1);
            advises[17].Should().BeSameAs(highlyRatedSongsAdvise2);
        }