public void PreviousAndNext()
        {
            var manager = new PlaylistManager();
            manager.AddAndReplaceItems(threeItems);

            Assert.IsFalse(manager.CanPreviousItem);
            Assert.IsFalse(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.CurrentItem = threeItems[0]);
            Assert.IsFalse(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanPreviousItem, () => manager.NextItem());
            Assert.AreEqual(threeItems[1], manager.CurrentItem);
            Assert.IsTrue(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.NextItem());
            Assert.AreEqual(threeItems[2], manager.CurrentItem);
            Assert.IsTrue(manager.CanPreviousItem);
            Assert.IsFalse(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.PreviousItem());
            Assert.AreEqual(threeItems[1], manager.CurrentItem);
            Assert.IsTrue(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);
        }
        protected override void OnInitialize()
        {
            base.OnInitialize();

            var musicFileContext = Container.GetExportedValue<MockMusicFileContext>();
            musicFiles = new ObservableCollection<MusicFile>()
            {
               musicFileContext.Create(@"C:\Users\Public\Music\Dancefloor\Culture Beat - Serenity.wav"),
               musicFileContext.Create(@"C:\Culture Beat - Serenity - Epilog.wma"),
            };
            selectionService = Container.GetExportedValue<SelectionService>();
            selectionService.Initialize(musicFiles);
            
            playlistManager = new PlaylistManager();
            playlistSettings = new PlaylistSettings();
            controller = Container.GetExportedValue<PlayerController>();
            controller.PlaylistSettings = playlistSettings;
            controller.PlaylistManager = playlistManager;
            controller.Initialize();

            shellService = Container.GetExportedValue<ShellService>();
            shellService.ShowPlaylistViewAction = () => { };
            view = (MockPlayerView)shellService.PlayerView;
            viewModel = ViewHelper.GetViewModel<PlayerViewModel>(view);
        }
 public SamplePlaylistViewModel() : base(new MockPlaylistView())
 {
     var musicFiles = new[] 
     {
         new SampleMusicFile(new MusicMetadata(new TimeSpan(0, 3, 45), 320000)
         {
             Artists = new[] { @"Culture Beat" },
             Title = @"Serenity (Epilog)",
         }, @"C:\Users\Public\Music\Dancefloor\Culture Beat - Serenity"),
         new SampleMusicFile(new MusicMetadata(new TimeSpan(0, 2, 2), 320000)
         {
             Artists = new[] { "First artist", "Second artist" },
             Title = "This track has a very long title. Let's see how the UI handles this.",
         }, ""),
         new SampleMusicFile(new MusicMetadata(new TimeSpan(1, 33, 0), 320000)
         {
             Artists = new string[0],
             Title = "",
         }, @"C:\Users\Public\Music\Dancefloor\Culture Beat - Serenity"),
         new MusicFile(x => { throw new InvalidOperationException("Sample exception."); }, @"C:\corruptfile.mp3")
     };
     var playlistManager = new PlaylistManager();
     playlistManager.AddItems(musicFiles.Select(x => new PlaylistItem(x)));
     PlaylistManager = playlistManager;
     playlistManager.CurrentItem = playlistManager.Items.First();
 }
 public SamplePlayerViewModel() : base(new MockPlayerView(), null, null)
 {
     var playlistManager = new PlaylistManager();
     playlistManager.CurrentItem = new PlaylistItem(new SampleMusicFile(new MusicMetadata(new TimeSpan(0, 3, 45), 320)
     {
         Artists = new[] { @"Culture Beat" },
         Title = @"Serenity (Epilog)",
         Genre = new[] { "Electronic", "Dance" }
     }, @"C:\Users\Public\Music\Dancefloor\Culture Beat - Serenity"));
     PlaylistManager = playlistManager;
 }
        public void SearchTextTest()
        {
            var viewModel = Container.GetExportedValue<PlaylistViewModel>();
            var view = Container.GetExportedValue<MockPlaylistView>();
            PlaylistItem scrollIntoViewItem = null;
            view.ScrollIntoViewStub = x => scrollIntoViewItem = x;
            bool focusSearchBoxCalled = false;
            view.FocusSearchBoxStub = () => focusSearchBoxCalled = true;

            var musicFiles = new[]
            {
                MockMusicFile.CreateEmpty(@"C:\Users\Public\Music\Dancefloor\Culture Beat - Serenity.wav"),
                MockMusicFile.CreateEmpty(@"C:\Future Breeze - Why don't you dance with me.mp3"),
                MockMusicFile.CreateEmpty(@"C:\Culture Beat - Serenity - Epilog.wma"),
            };
            var playlistManager = new PlaylistManager();
            playlistManager.AddAndReplaceItems(musicFiles.Select(x => new PlaylistItem(x)));
            viewModel.PlaylistManager = playlistManager;
            
            viewModel.SearchText = "Bill";
            Assert.IsNull(viewModel.SelectedPlaylistItem);
            Assert.IsNull(scrollIntoViewItem);
            Assert.IsTrue(focusSearchBoxCalled);

            viewModel.SearchText = "Cul";
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[0], scrollIntoViewItem);

            // Selection stays on the same item
            viewModel.SearchText = "Cultur";
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[0], scrollIntoViewItem);

            viewModel.SearchText = "Epi";
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[2], scrollIntoViewItem);

            // Selection stays on the same item
            scrollIntoViewItem = null;
            viewModel.SearchText = "";
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);
            Assert.IsNull(scrollIntoViewItem);

            viewModel.SelectedPlaylistItem = playlistManager.Items[1];

            // Search starts from selection
            viewModel.SearchText = "Cul";
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[2], scrollIntoViewItem);
        }
        public void PreviousAndNextWithShuffle()
        {
            var randomService = new MockRandomService();
            int randomNumber = 0;
            int lastMaxValue = -1;
            randomService.NextRandomNumberStub = maxValue =>
            {
                lastMaxValue = maxValue;
                return randomNumber;
            };

            var manager = new PlaylistManager(3, randomService);
            manager.AddAndReplaceItems(threeItems);
            manager.Shuffle = true;

            Assert.IsFalse(manager.CanPreviousItem);
            Assert.IsFalse(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.CurrentItem = threeItems[0]);
            Assert.IsFalse(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);

            randomNumber = 1;
            AssertHelper.PropertyChangedEvent(manager, x => x.CanPreviousItem, () => manager.NextItem());
            Assert.AreEqual(1, lastMaxValue);
            Assert.AreEqual(threeItems[2], manager.CurrentItem);
            Assert.IsTrue(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);

            randomNumber = 0;
            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.NextItem());
            Assert.AreEqual(0, lastMaxValue);
            Assert.AreEqual(threeItems[1], manager.CurrentItem);
            Assert.IsTrue(manager.CanPreviousItem);
            Assert.IsFalse(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.PreviousItem());
            Assert.AreEqual(threeItems[2], manager.CurrentItem);
            Assert.IsTrue(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);

            AssertHelper.PropertyChangedEvent(manager, x => x.CanPreviousItem, () => manager.PreviousItem());
            Assert.AreEqual(threeItems[0], manager.CurrentItem);
            Assert.IsFalse(manager.CanPreviousItem);
            Assert.IsTrue(manager.CanNextItem);
        }
        public void SearchNextAndPrevious()
        {
            var viewModel = Container.GetExportedValue<PlaylistViewModel>();
            var view = Container.GetExportedValue<MockPlaylistView>();
            
            var musicFiles = new[]
            {
                MockMusicFile.CreateEmpty(@"C:\Culture Beat"),
                MockMusicFile.CreateEmpty(@"C:\Culture Beat"),
                MockMusicFile.CreateEmpty(@"C:\Culture Beat"),
                MockMusicFile.CreateEmpty(@"C:\Foo"),
            };
            var playlistManager = new PlaylistManager();
            playlistManager.AddAndReplaceItems(musicFiles.Select(x => new PlaylistItem(x)));
            viewModel.PlaylistManager = playlistManager;

            viewModel.SearchText = "Culture";
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);

            viewModel.SearchNextCommand.Execute(null);
            Assert.AreEqual(playlistManager.Items[1], viewModel.SelectedPlaylistItem);

            viewModel.SearchNextCommand.Execute(null);
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);
            
            viewModel.SearchNextCommand.Execute(null);
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);

            viewModel.SearchPreviousCommand.Execute(null);
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);

            viewModel.SearchPreviousCommand.Execute(null);
            Assert.AreEqual(playlistManager.Items[1], viewModel.SelectedPlaylistItem);

            viewModel.SearchPreviousCommand.Execute(null);
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);
        }
        public void SearchTextIsContainedTest()
        {
            var viewModel = Container.GetExportedValue<PlaylistViewModel>();
            var view = Container.GetExportedValue<MockPlaylistView>();
            PlaylistItem scrollIntoViewItem = null;
            view.ScrollIntoViewStub = x => scrollIntoViewItem = x;

            var musicFiles = new[]
            {
                CreateMockMusicFile(@"C:\Music\Foo.mp3", "1 title", "1 artist"),
                CreateMockMusicFile(@"C:\Music\Baz.wma", "2 TiTle", "2 ArTisT"),
                CreateMockMusicFile(@"C:\Music\Abc.mp3", "3 TITLE", "3a artist", "3B ARTIST"),
                new MusicFile(x => Task.FromResult((MusicMetadata)null), "do not load"),
            };
            var playlistManager = new PlaylistManager();
            playlistManager.AddAndReplaceItems(musicFiles.Select(x => new PlaylistItem(x)));
            viewModel.PlaylistManager = playlistManager;

            viewModel.SearchText = "1 TIT";
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[0], scrollIntoViewItem);

            viewModel.SearchText = "1 ART";
            Assert.AreEqual(playlistManager.Items[0], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[0], scrollIntoViewItem);

            viewModel.SearchText = "3B art";
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);
            Assert.AreEqual(playlistManager.Items[2], scrollIntoViewItem);

            // File name is not considered as Title & Artist are set and shown.
            scrollIntoViewItem = null;
            viewModel.SearchText = "baz";
            Assert.AreEqual(playlistManager.Items[2], viewModel.SelectedPlaylistItem);
            Assert.IsNull(scrollIntoViewItem);

            // Ensure that the search feature does not load the metadata of all Playlist items.
            Assert.IsFalse(musicFiles.Last().IsMetadataLoaded);
        }
        public void TotalDurationWithMetadataLoading()
        {
            var manager = new PlaylistManager();
            Assert.AreEqual(TimeSpan.Zero, manager.TotalDuration);
            var firstFile = new MockMusicFile(new MusicMetadata(TimeSpan.FromSeconds(10), 0), "");
            manager.AddAndReplaceItems(new[] { new PlaylistItem(firstFile) });
            
            var secondMetadata = new MusicMetadata(TimeSpan.FromSeconds(20), 0);
            var secondFile = new MusicFile(async x =>
            {
                await Task.Delay(10);
                return secondMetadata;
            }, "");

            manager.AddItems(new[] { new PlaylistItem(secondFile) });
            Assert.IsTrue(manager.IsTotalDurationEstimated);
            Assert.AreEqual(TimeSpan.FromSeconds(20), manager.TotalDuration);
            AssertHelper.PropertyChangedEvent(manager, x => x.TotalDuration, () => secondFile.GetMetadataAsync().GetResult());
            Assert.IsFalse(manager.IsTotalDurationEstimated);
            Assert.AreEqual(TimeSpan.FromSeconds(30), manager.TotalDuration);

            var thirdFile = new MockMusicFile(new MusicMetadata(TimeSpan.FromSeconds(30), 0), "");
            AssertHelper.PropertyChangedEvent(manager, x => x.TotalDuration, () => manager.AddItems(new[] { new PlaylistItem(thirdFile) }));
            Assert.AreEqual(TimeSpan.FromSeconds(60), manager.TotalDuration);
        }
        public void AddRemoveAndMoveItems()
        {
            var manager = new PlaylistManager();
            Assert.AreEqual(0, manager.Items.Count);

            manager.AddItems(threeItems);
            Assert.AreEqual(3, manager.Items.Count);

            manager.RemoveItems(new[] { threeItems[2] });
            Assert.AreEqual(2, manager.Items.Count);

            manager.AddAndReplaceItems(threeItems);
            Assert.AreEqual(3, manager.Items.Count);

            manager.MoveItems(2, new[] { manager.Items[0] });
            Assert.IsTrue(manager.Items.SequenceEqual(new[] { threeItems[1], threeItems[2], threeItems[0] }));
        }
        public void NextWithShuffleAndRepeatAndOneItem()
        {
            var manager = new PlaylistManager();
            manager.AddAndReplaceItems(threeItems.Take(1));
            manager.Shuffle = true;
            manager.Repeat = true;
            manager.CurrentItem = threeItems[0];

            manager.NextItem();
            Assert.AreEqual(threeItems[0], manager.CurrentItem);
        }
        public void PreviousAndNextWithClear()
        {
            var manager = new PlaylistManager();
            manager.AddAndReplaceItems(threeItems);
            manager.CurrentItem = threeItems[1];

            Assert.IsTrue(manager.CanPreviousItem);
            AssertHelper.PropertyChangedEvent(manager, x => x.CanPreviousItem, () => manager.ClearItems());
            Assert.IsFalse(manager.CanPreviousItem);
            AssertHelper.ExpectedException<InvalidOperationException>(() => manager.PreviousItem());

            manager.AddAndReplaceItems(threeItems);
            manager.CurrentItem = threeItems[1];

            Assert.IsTrue(manager.CanNextItem);
            AssertHelper.PropertyChangedEvent(manager, x => x.CanNextItem, () => manager.ClearItems());
            Assert.IsFalse(manager.CanNextItem);
            AssertHelper.ExpectedException<InvalidOperationException>(() => manager.NextItem());
        }
        public void PreviousAndNextWithRepeat()
        {
            var manager = new PlaylistManager();
            manager.AddAndReplaceItems(threeItems);
            manager.Repeat = true;
            manager.CurrentItem = threeItems[0];

            for (int i = 0; i < 5; i++)
            {
                Assert.AreEqual(threeItems[i % 3], manager.CurrentItem);
                Assert.IsTrue(manager.CanNextItem);
                manager.NextItem();
            }

            manager.Shuffle = true;

            for (int i = 0; i < 5; i++)
            {
                Assert.IsTrue(manager.CanNextItem);
                manager.NextItem();
            }
        }
        public void ResetNextWithShuffle()
        {
            var manager = new PlaylistManager();
            manager.AddAndReplaceItems(threeItems);
            manager.Shuffle = true;
            manager.CurrentItem = threeItems[0];

            for (int i = 0; i < 2; i++)
            {
                Assert.IsTrue(manager.CanNextItem);
                manager.NextItem();
            }

            Assert.IsFalse(manager.CanNextItem);

            manager.Reset();

            for (int i = 0; i < 2; i++)
            {
                Assert.IsTrue(manager.CanNextItem);
                manager.NextItem();
            }

            Assert.IsFalse(manager.CanNextItem);
        }