diff --git a/Play.Tests/Play.Tests.csproj b/Play.Tests/Play.Tests.csproj
index 7230afd..651267b 100644
--- a/Play.Tests/Play.Tests.csproj
+++ b/Play.Tests/Play.Tests.csproj
@@ -117,6 +117,7 @@
+
diff --git a/Play.Tests/ViewModels/SearchViewModel.cs b/Play.Tests/ViewModels/SearchViewModel.cs
new file mode 100644
index 0000000..9986933
--- /dev/null
+++ b/Play.Tests/ViewModels/SearchViewModel.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive;
+using System.Reactive.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Moq;
+using Ninject;
+using Ninject.MockingKernel.Moq;
+using Play.Models;
+using ReactiveUI;
+using ReactiveUI.Routing;
+using ReactiveUI.Xaml;
+using Xunit;
+
+namespace Play.Tests.ViewModels
+{
+ public class SearchViewModelTests
+ {
+ [Fact]
+ public void PlayApiShouldBeCalledOnPerformSearch()
+ {
+ var kernel = new MoqMockingKernel();
+
+ kernel.GetMock()
+ .Setup(x => x.Search("Foo"))
+ .Returns(Observable.Return(new List() { new Song() { id = "12345" } }))
+ .Verifiable();
+
+ var fixture = kernel.Get();
+ fixture.PerformSearch.CanExecute(null).Should().BeFalse();
+
+ fixture.SearchQuery = "Foo";
+ fixture.PerformSearch.CanExecute(null).Should().BeTrue();
+ fixture.PerformSearch.Execute(null);
+
+ kernel.GetMock().Verify(x => x.Search("Foo"), Times.Once());
+
+ fixture.SearchResults.Count.Should().Be(1);
+ fixture.SearchResults[0].Model.id.Should().Be("12345");
+ }
+ }
+
+ public interface ISearchViewModel : IRoutableViewModel
+ {
+ string SearchQuery { get; set; }
+
+ ReactiveCollection SearchResults { get; }
+ ReactiveAsyncCommand PerformSearch { get; }
+ }
+
+ public interface ISearchResultTileViewModel : IReactiveNotifyPropertyChanged
+ {
+ Song Model { get; }
+
+ ReactiveCommand QueueSong { get; }
+ ReactiveCommand QueueAlbum { get; }
+ ReactiveCommand ShowSongsFromArtist { get; }
+ ReactiveCommand ShowSongsFromAlbum { get; }
+ }
+}
\ No newline at end of file