Skip to content
Permalink
Browse files

Added SearchAlbums & SearchAlbumsAsync to client

  • Loading branch information...
mrlacey committed Jul 21, 2013
1 parent bcd314d commit af5b53c236e0072a553d68b53c93711ff510e6c6
@@ -0,0 +1,67 @@
// -----------------------------------------------------------------------
// <copyright file="SearchAlbumsCommand.cs" company="Nokia">
// Copyright (c) 2013, Nokia
// All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using Nokia.Music.Types;

namespace Nokia.Music.Commands
{
/// <summary>
/// Searches for an Album
/// </summary>
internal sealed class SearchAlbumsCommand : SearchCatalogCommand<Product>
{
/// <summary>
/// Gets or sets the search term.
/// </summary>
public string SearchTerm { get; set; }

/// <summary>
/// Gets or sets the latitude and longitude to search around.
/// </summary>
/// <value>
/// The location.
/// </value>
public Location Location { get; set; }

/// <summary>
/// Gets or sets the max distance to search around the location.
/// </summary>
/// <value>
/// The max distance.
/// </value>
public int MaxDistance { get; set; }

/// <summary>
/// Executes the command
/// </summary>
/// <exception cref="System.ArgumentNullException">SearchTerm;A searchTerm must be supplied</exception>
protected override void Execute()
{
if (string.IsNullOrEmpty(this.SearchTerm) && (this.Location == null || (this.Location.Latitude == 0 || this.Location.Longitude == 0)))
{
throw new ArgumentNullException("SearchTerm", "A searchTerm or location must be supplied");
}

string location = null;
string maxdistance = null;

if (this.Location != null)
{
location = this.Location.ToString();
}

if (this.MaxDistance > 0)
{
maxdistance = this.MaxDistance.ToString();
}

this.InternalSearch(this.SearchTerm, null, Category.Album, location, maxdistance, this.StartIndex, this.ItemsPerPage, Product.FromJToken, this.Callback);
}
}
}
@@ -39,6 +39,28 @@ public partial interface IMusicClient
/// <returns>A ListResponse containing Artists or an Error</returns>
Task<ListResponse<Artist>> SearchArtistsAsync(string searchTerm, int startIndex = MusicClient.DefaultStartIndex, int itemsPerPage = MusicClient.DefaultItemsPerPage);

#endif
#if !NETFX_CORE
/// <summary>
/// Searches for an Album
/// </summary>
/// <param name="callback">The callback to use when the API call has completed</param>
/// <param name="searchTerm">The search term.</param>
/// <param name="startIndex">The zero-based start index to fetch items from (e.g. to get the second page of 10 items, pass in 10).</param>
/// <param name="itemsPerPage">The number of items to fetch.</param>
void SearchAlbums(Action<ListResponse<Product>> callback, string searchTerm, int startIndex = MusicClient.DefaultStartIndex, int itemsPerPage = MusicClient.DefaultItemsPerPage);

#endif
#if SUPPORTS_ASYNC
/// <summary>
/// Searches for an Album
/// </summary>
/// <param name="searchTerm">The search term.</param>
/// <param name="startIndex">The zero-based start index to fetch items from (e.g. to get the second page of 10 items, pass in 10).</param>
/// <param name="itemsPerPage">The number of items to fetch.</param>
/// <returns>A ListResponse containing Artists or an Error</returns>
Task<ListResponse<Product>> SearchAlbumsAsync(string searchTerm, int startIndex = MusicClient.DefaultStartIndex, int itemsPerPage = MusicClient.DefaultItemsPerPage);

#endif
#if !NETFX_CORE
/// <summary>
@@ -179,6 +179,38 @@ public Task<ListResponse<Artist>> SearchArtistsAsync(string searchTerm, int star
return wrapper.Task;
}

#endif
#if !NETFX_CORE
/// <summary>
/// Searches for an Album
/// </summary>
/// <param name="callback">The callback to use when the API call has completed</param>
/// <param name="searchTerm">The search term.</param>
/// <param name="startIndex">The zero-based start index to fetch items from (e.g. to get the second page of 10 items, pass in 10).</param>
/// <param name="itemsPerPage">The number of items to fetch.</param>
public void SearchAlbums(Action<ListResponse<Product>> callback, string searchTerm, int startIndex = MusicClient.DefaultStartIndex, int itemsPerPage = MusicClient.DefaultItemsPerPage)
{
this.SearchAlbumsInternal(callback, searchTerm, startIndex, itemsPerPage);
}

#endif
#if SUPPORTS_ASYNC
/// <summary>
/// Searches for an Album
/// </summary>
/// <param name="searchTerm">The search term.</param>
/// <param name="startIndex">The zero-based start index to fetch items from (e.g. to get the second page of 10 items, pass in 10).</param>
/// <param name="itemsPerPage">The number of items to fetch.</param>
/// <returns>
/// A ListResponse containing Album or an Error
/// </returns>
public Task<ListResponse<Product>> SearchAlbumsAsync(string searchTerm, int startIndex = MusicClient.DefaultStartIndex, int itemsPerPage = MusicClient.DefaultItemsPerPage)
{
var wrapper = new TaskCompletionSource<ListResponse<Product>>();
this.SearchAlbumsInternal(result => wrapper.TrySetResult(result), searchTerm, startIndex, itemsPerPage);
return wrapper.Task;
}

#endif
#if !NETFX_CORE
/// <summary>
@@ -1130,6 +1162,22 @@ private void SearchArtistsInternal(Action<ListResponse<Artist>> callback, string
cmd.Invoke(callback);
}

/// <summary>
/// Searches for an Album
/// </summary>
/// <param name="callback">The callback to use when the API call has completed</param>
/// <param name="searchTerm">The search term.</param>
/// <param name="startIndex">The zero-based start index to fetch items from (e.g. to get the second page of 10 items, pass in 10).</param>
/// <param name="itemsPerPage">The number of items to fetch.</param>
private void SearchAlbumsInternal(Action<ListResponse<Product>> callback, string searchTerm, int startIndex = MusicClient.DefaultStartIndex, int itemsPerPage = MusicClient.DefaultItemsPerPage)
{
var cmd = this.Create<SearchAlbumsCommand>();
cmd.SearchTerm = searchTerm;
cmd.StartIndex = startIndex;
cmd.ItemsPerPage = itemsPerPage;
cmd.Invoke(callback);
}

/// <summary>
/// Gets artist search suggestions.
/// </summary>
@@ -57,6 +57,7 @@
<Compile Include="Commands\NewReleasesCommand.cs" />
<Compile Include="Commands\ProductCommand.cs" />
<Compile Include="Commands\SearchArtistsCommand.cs" />
<Compile Include="Commands\SearchAlbumsCommand.cs" />
<Compile Include="Commands\SearchCatalogCommand.cs" />
<Compile Include="Commands\SearchCommand.cs" />
<Compile Include="Commands\SearchSuggestionsCommand.cs" />
@@ -123,6 +123,8 @@
</Compile>
<Compile Include="Commands\SearchArtistsCommand.cs">
</Compile>
<Compile Include="Commands\SearchAlbumsCommand.cs">
</Compile>
<Compile Include="Commands\SearchCatalogCommand.cs">
</Compile>
<Compile Include="Commands\SearchCommand.cs">
@@ -117,6 +117,7 @@
<Compile Include="Commands\SearchCatalogCommand.cs" />
<Compile Include="Commands\SearchSuggestionsCommand.cs" />
<Compile Include="Commands\SimilarArtistsCommand.cs" />
<Compile Include="Commands\SearchAlbumsCommand.cs" />
<Compile Include="Commands\SimilarProductsCommand.cs" />
<Compile Include="Converters\LocationConverter.cs" />
<Compile Include="CountryResolver.cs" />
@@ -113,6 +113,7 @@
<Compile Include="Commands\MusicClientCommand{TReturnType}.cs" />
<Compile Include="Commands\NewReleasesCommand.cs" />
<Compile Include="Commands\SearchArtistsCommand.cs" />
<Compile Include="Commands\SearchAlbumsCommand.cs" />
<Compile Include="Commands\SearchCommand.cs" />
<Compile Include="Commands\SimilarArtistsCommand.cs" />
<Compile Include="Commands\SimilarProductsCommand.cs" />
@@ -81,6 +81,7 @@
<StackPanel Orientation="Vertical" Margin="0,18,0,0">
<TextBlock Text="Try out the search APIs" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap" />
<Button Content="Search Artists" Click="SearchArtists" x:Name="SearchArtistsButton" IsEnabled="False" />
<Button Content="Search Albums" Click="SearchAlbums" x:Name="SearchAlbumsButton" IsEnabled="False" />
<Button Content="Search" Click="Search" x:Name="SearchButton" IsEnabled="False" />
</StackPanel>

@@ -173,6 +173,7 @@ private void EnableCountrySpecificApiButtons(string countryCode)

// enable / disable API test buttons...
this.SearchArtistsButton.IsEnabled = countryCode != null;
this.SearchAlbumsButton.IsEnabled = countryCode != null;
this.SearchButton.IsEnabled = countryCode != null;
this.TopArtistsButton.IsEnabled = countryCode != null;
this.GenresButton.IsEnabled = countryCode != null;
@@ -192,6 +193,16 @@ private void SearchArtists(object sender, RoutedEventArgs e)
NavigationService.Navigate(new Uri("/SearchPage.xaml?" + SearchPage.SearchScopeParam + "=" + SearchPage.SearchScopeArtists, UriKind.Relative));
}

/// <summary>
/// Navigates to SearchPage in album search scope.
/// </summary>
/// <param name="sender">Search Albums button</param>
/// <param name="e">Event arguments</param>
private void SearchAlbums(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/SearchPage.xaml?" + SearchPage.SearchScopeParam + "=" + SearchPage.SearchScopeAlbums, UriKind.Relative));
}

/// <summary>
/// Navigates to SearchPage.
/// </summary>
@@ -36,8 +36,15 @@ public partial class SearchPage : PhoneApplicationPage
/// </summary>
public const string SearchScopeArtists = "artists";

/// <summary>
/// Constant for search scope for albums.
/// </summary>
public const string SearchScopeAlbums = "albums";

private bool _artistSearch = false;

private bool _albumSearch = false;

/// <summary>
/// Constructor for SearchPage.
/// </summary>
@@ -58,12 +65,17 @@ protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventA
if (NavigationContext.QueryString.ContainsKey(SearchScopeParam))
{
this._artistSearch = string.CompareOrdinal(NavigationContext.QueryString[SearchScopeParam], SearchScopeArtists) == 0;
this._albumSearch = string.CompareOrdinal(NavigationContext.QueryString[SearchScopeParam], SearchScopeAlbums) == 0;
}

if (this._artistSearch)
{
this.PageTitle.Text = "artist search";
}
else if (this._albumSearch)
{
this.PageTitle.Text = "album search";
}
else
{
this.PageTitle.Text = "search";
@@ -94,8 +106,9 @@ private void SearchPopulating(object sender, PopulatingEventArgs e)
{
App.ApiClient.GetArtistSearchSuggestions(this.HandleSearchSuggestionsResponse, e.Parameter);
}
else
else if (!this._albumSearch)
{
// No search suggestions for albums
App.ApiClient.GetSearchSuggestions(this.HandleSearchSuggestionsResponse, e.Parameter);
}
}
@@ -157,6 +170,10 @@ private void PerformSearch(object sender, RoutedEventArgs e)
{
App.ApiClient.SearchArtists(this.ResponseHandler, this.SearchTerm.Text, 0, 20);
}
else if (this._artistSearch)
{
App.ApiClient.SearchAlbums(this.ResponseHandler, this.SearchTerm.Text, 0, 20);
}
else
{
App.ApiClient.Search(this.ResponseHandler, this.SearchTerm.Text, itemsPerPage: 20);
@@ -81,6 +81,7 @@
<StackPanel Orientation="Vertical" Margin="0,18,0,0">
<TextBlock Text="Try out the search APIs" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap" />
<Button Content="Search Artists" Click="SearchArtists" x:Name="SearchArtistsButton" IsEnabled="False" />
<Button Content="Search Albums" Click="SearchAlbums" x:Name="SearchAlbumsButton" IsEnabled="False" />
<Button Content="Search" Click="Search" x:Name="SearchButton" IsEnabled="False" />
</StackPanel>

@@ -0,0 +1,91 @@
// -----------------------------------------------------------------------
// <copyright file="SearchAlbumsTests.cs" company="Nokia">
// Copyright (c) 2013, Nokia
// All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Net;
using Nokia.Music.Tests.Properties;
using Nokia.Music.Types;
using NUnit.Framework;

namespace Nokia.Music.Tests.Commands
{
[TestFixture]
public class SearchAlbumsTests
{
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void EnsureSearchAlbumsThrowsExceptionForNullSearchTerm()
{
IMusicClient client = new MusicClient("test", "gb", new MockApiRequestHandler(Resources.search_albums));
client.SearchAlbums((ListResponse<Product> result) => { }, null);
}

[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void EnsureSearchAlbumsThrowsExceptionForNullCallback()
{
IMusicClient client = new MusicClient("test", "gb", new MockApiRequestHandler(Resources.search_albums));
client.SearchAlbums(null, @"best");
}

[Test]
public void EnsureSearchArtistsReturnsArtistsForValidSearch()
{
IMusicClient client = new MusicClient("test", "gb", new MockApiRequestHandler(Resources.search_albums));
client.SearchAlbums(
(ListResponse<Product> result) =>
{
Assert.IsNotNull(result, "Expected a result");
Assert.IsNotNull(result.StatusCode, "Expected a status code");
Assert.IsTrue(result.StatusCode.HasValue, "Expected a status code");
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode.Value, "Expected a 200 response");
Assert.IsNotNull(result.Result, "Expected a list of results");
Assert.IsNull(result.Error, "Expected no error");
Assert.Greater(result.Result.Count, 0, "Expected more than 0 results");

foreach (Product album in result.Result)
{
Assert.IsFalse(string.IsNullOrEmpty(album.Id), "Expected Id to be populated");
Assert.IsFalse(string.IsNullOrEmpty(album.Name), "Expected Name to be populated");
Assert.IsNotNull(album.Genres, "Expected a genre list");
Assert.Greater(album.Genres.Length, 0, "Expected more than 0 genres");
}
},
"best");
}

/// <summary>
/// The faked SearchAlbums response Returns no results found
/// </summary>
[Test]
public void EnsureSearchAlbumsReturnsErrorForFailedCall()
{
IMusicClient client = new MusicClient("test", "gb", new MockApiRequestHandler(Resources.search_noresults));
client.SearchAlbums(
(ListResponse<Product> result) =>
{
Assert.IsNotNull(result, "Expected a result");
Assert.IsNotNull(result.StatusCode, "Expected a status code");
Assert.IsTrue(result.StatusCode.HasValue, "Expected a status code");
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode.Value, "Expected a 200 response");
Assert.IsNotNull(result.Result, "Expected a list of results");
Assert.IsNull(result.Error, "Expected no error");
Assert.AreEqual(result.Result.Count, 0, "Expected 0 results");
},
"best");
}

[Test]
public async void EnsureAsyncSearchAlbumsReturnsItems()
{
// Only test happy path, as the MusicClient tests cover the unhappy path
IMusicClient client = new MusicClient("test", "gb", new MockApiRequestHandler(Resources.search_albums));
ListResponse<Product> result = await client.SearchAlbumsAsync("test");
Assert.Greater(result.Result.Count, 0, "Expected more than 0 results");
}
}
}

0 comments on commit af5b53c

Please sign in to comment.
You can’t perform that action at this time.