mirror of
https://github.com/Sarsoo/IF.Lastfm.git
synced 2024-10-17 07:13:09 +01:00
Made PageResponse<T> covariant and readonly, changed signature of PageResponse.CreateSuccessResponse method, tests for album.getTagsByUserCommand
This commit is contained in:
parent
74da6afee5
commit
b49b0aa442
@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using IF.Lastfm.Core.Api.Commands.AlbumApi;
|
||||
using IF.Lastfm.Core.Api.Enums;
|
||||
using IF.Lastfm.Core.Objects;
|
||||
using IF.Lastfm.Core.Tests.Resources;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace IF.Lastfm.Core.Tests.Api.Commands
|
||||
{
|
||||
[TestClass]
|
||||
public class AlbumGetTagsByUserCommandTests : CommandTestsBase
|
||||
{
|
||||
private AlbumGetTagsByUserCommand _command;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialise()
|
||||
{
|
||||
_command = new AlbumGetTagsByUserCommand(MAuth.Object, "", "", "");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task HandleResponseSingle()
|
||||
{
|
||||
var expectedTags = new List<LastTag>
|
||||
{
|
||||
new LastTag("Test Tag", "http://www.last.fm/tag/test%20tag")
|
||||
};
|
||||
|
||||
var response = CreateResponseMessage(Encoding.UTF8.GetString(AlbumApiResponses.AlbumGetTagsSingle));
|
||||
var parsed = await _command.HandleResponse(response);
|
||||
|
||||
var expectedJson = expectedTags.TestSerialise();
|
||||
var actualJson = parsed.Content.TestSerialise();
|
||||
|
||||
parsed.AssertValues(true, 1, 1, 1, 1);
|
||||
Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task HandleResponseMultiple()
|
||||
{
|
||||
var expectedTags = new List<LastTag>
|
||||
{
|
||||
new LastTag("test tag 2: electric boogaloo", "http://www.last.fm/tag/test%20tag%202%3A%20electric%20boogaloo"),
|
||||
new LastTag("Test Tag", "http://www.last.fm/tag/test%20tag")
|
||||
};
|
||||
|
||||
var response = CreateResponseMessage(Encoding.UTF8.GetString(AlbumApiResponses.AlbumGetTagsMultiple));
|
||||
var parsed = await _command.HandleResponse(response);
|
||||
|
||||
var expectedJson = expectedTags.TestSerialise();
|
||||
var actualJson = parsed.Content.TestSerialise();
|
||||
|
||||
parsed.AssertValues(true, 2, 2, 1, 1);
|
||||
Assert.AreEqual(expectedJson, actualJson, expectedJson.DifferencesTo(actualJson));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task HandleResponseEmpty()
|
||||
{
|
||||
var response = CreateResponseMessage(Encoding.UTF8.GetString(AlbumApiResponses.AlbumGetTagsEmpty));
|
||||
var parsed = await _command.HandleResponse(response);
|
||||
|
||||
parsed.AssertValues(true, 0, 0, 1, 1);
|
||||
Assert.IsTrue(!parsed.Content.Any());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task HandleResponseError()
|
||||
{
|
||||
var response = CreateResponseMessage(Encoding.UTF8.GetString(AlbumApiResponses.AlbumGetTagsError));
|
||||
var parsed = await _command.HandleResponse(response);
|
||||
|
||||
parsed.AssertValues(false, 0, 0, 1, 1);
|
||||
Assert.IsFalse(parsed.Success);
|
||||
Assert.IsTrue(parsed.Error == LastFmApiError.MissingParameters);
|
||||
Assert.IsTrue(!parsed.Content.Any());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using IF.Lastfm.Core.Api;
|
||||
using System.Threading.Tasks;
|
||||
using IF.Lastfm.Core.Api;
|
||||
using IF.Lastfm.Core.Api.Commands;
|
||||
using IF.Lastfm.Core.Api.Helpers;
|
||||
using IF.Lastfm.Core.Objects;
|
||||
@ -8,7 +9,6 @@
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IF.Lastfm.Core.Tests.Api.Commands
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="Moq, Version=4.2.1409.1722, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@ -78,6 +79,7 @@
|
||||
<Compile Include="Api\Commands\AlbumApi\GetAlbumShoutsCommandTests.cs" />
|
||||
<Compile Include="Api\Commands\AlbumApi\GetAlbumTopTagsCommandTest.cs" />
|
||||
<Compile Include="Api\Commands\AlbumApi\SearchAlbumsCommandTests.cs" />
|
||||
<Compile Include="Api\Commands\AlbumGetTagsByUserCommandTests.cs" />
|
||||
<Compile Include="Api\Commands\CommandTestsBase.cs" />
|
||||
<Compile Include="Api\Commands\Library\LibraryGetTracksCommandTests.cs" />
|
||||
<Compile Include="Api\Commands\TrackApi\GetTrackShoutsCommandTests.cs" />
|
||||
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"tags": {
|
||||
"#text": "\n",
|
||||
"artist": "Hot Chip",
|
||||
"album": "Made in the Dark"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"error": 6,
|
||||
"message": "Invalid user supplied",
|
||||
"links": []
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
{
|
||||
"tags": {
|
||||
"tag": [
|
||||
{
|
||||
"name": "test tag 2: electric boogaloo",
|
||||
"url": "http://www.last.fm/tag/test%20tag%202%3A%20electric%20boogaloo"
|
||||
},
|
||||
{
|
||||
"name": "Test Tag",
|
||||
"url": "http://www.last.fm/tag/test%20tag"
|
||||
}
|
||||
],
|
||||
"@attr": {
|
||||
"artist": "Hot Chip",
|
||||
"album": "Coming on Strong"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"tags": {
|
||||
"tag": {
|
||||
"name": "Test Tag",
|
||||
"url": "http://www.last.fm/tag/test%20tag"
|
||||
},
|
||||
"@attr": {
|
||||
"artist": "Hot Chip",
|
||||
"album": "The Warning"
|
||||
}
|
||||
}
|
||||
}
|
@ -120,6 +120,46 @@ internal static byte[] AlbumGetShoutsSingle {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] AlbumGetTagsEmpty {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("AlbumGetTagsEmpty", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] AlbumGetTagsError {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("AlbumGetTagsError", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] AlbumGetTagsMultiple {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("AlbumGetTagsMultiple", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] AlbumGetTagsSingle {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("AlbumGetTagsSingle", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
|
@ -136,6 +136,18 @@
|
||||
<data name="AlbumGetShoutsSingle" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>albumapi\albumgetshoutssingle.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="AlbumGetTagsEmpty" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>AlbumApi\AlbumGetTagsEmpty.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="AlbumGetTagsError" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>AlbumApi\AlbumGetTagsError.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="AlbumGetTagsMultiple" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>AlbumApi\AlbumGetTagsMultiple.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="AlbumGetTagsSingle" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>AlbumApi\AlbumGetTagsSingle.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="AlbumGetTopTags" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>AlbumApi\AlbumGetTopTags.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
|
@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using IF.Lastfm.Core.Api.Helpers;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace IF.Lastfm.Core.Tests
|
||||
@ -83,5 +85,22 @@ public static DateTime RoundToNearestSecond(this DateTime dt)
|
||||
? dt.AddMilliseconds(-ms)
|
||||
: dt.AddMilliseconds(1000 - ms);
|
||||
}
|
||||
|
||||
public static void AssertValues<T>(this PageResponse<T> pageResponse, bool success, int totalItems, int pageSize, int page, int totalPages)
|
||||
where T : new()
|
||||
{
|
||||
const string messageFormat = "Page response:\n{0}\n\nExpected {1} to equal {2}";
|
||||
var json = pageResponse.TestSerialise();
|
||||
Func<string, dynamic, string> testMessage = (property, count) => string.Format(messageFormat, json, property, count);
|
||||
|
||||
Assert.IsTrue(pageResponse.Success == success, testMessage("success", success));
|
||||
Assert.IsTrue(pageResponse.TotalItems == totalItems, testMessage("totalitems", totalItems));
|
||||
Assert.IsTrue(pageResponse.PageSize == pageSize, testMessage("pagesize", pageSize));
|
||||
Assert.IsTrue(pageResponse.Page == page, testMessage("page", page));
|
||||
Assert.IsTrue(pageResponse.TotalPages == totalPages, testMessage("totalpages", totalPages));
|
||||
|
||||
Assert.IsNotNull(pageResponse.Content, "page content is null");
|
||||
Assert.IsTrue(pageResponse.Content.Count == totalItems, testMessage("content length", totalItems));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,14 +36,19 @@ public async Task<LastResponse<LastAlbum>> GetAlbumInfoByMbidAsync(string albumM
|
||||
return await command.ExecuteAsync();
|
||||
}
|
||||
|
||||
public Task<PageResponse<BuyLink>> GetBuyLinksForAlbumAsync(string artist, string album, CountryCode country, bool autocorrect = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
//public Task<PageResponse<BuyLink>> GetBuyLinksForAlbumAsync(string artist, string album, CountryCode country, bool autocorrect = false)
|
||||
//{
|
||||
// throw new NotImplementedException();
|
||||
//}
|
||||
|
||||
public Task<PageResponse<LastTag>> GetUserTagsForAlbumAsync(string artist, string album, string username, bool autocorrect = false)
|
||||
public Task<PageResponse<LastTag>> GetTagsByUserAsync(string artist, string album, string username, bool autocorrect = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var command = new AlbumGetTagsByUserCommand(Auth, artist, album, username)
|
||||
{
|
||||
Autocorrect = autocorrect
|
||||
};
|
||||
|
||||
return command.ExecuteAsync();
|
||||
}
|
||||
|
||||
public async Task<PageResponse<LastTag>> GetTopTagsForAlbumAsync(string artist, string album, bool autocorrect = false)
|
||||
|
@ -12,40 +12,31 @@
|
||||
|
||||
namespace IF.Lastfm.Core.Api.Commands.AlbumApi
|
||||
{
|
||||
internal class GetUserTagsForAlbumCommand: GetAsyncCommandBase<PageResponse<LastTag>>
|
||||
internal class AlbumGetTagsByUserCommand : GetAsyncCommandBase<PageResponse<LastTag>>
|
||||
{
|
||||
public string AlbumMbid { get; set; }
|
||||
|
||||
public string ArtistName { get; set; }
|
||||
|
||||
public string AlbumName { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
public string Username { get; set; }
|
||||
|
||||
public bool Autocorrect { get; set; }
|
||||
|
||||
public GetUserTagsForAlbumCommand(ILastAuth auth, string album, string artist, string username)
|
||||
public AlbumGetTagsByUserCommand(ILastAuth auth, string artist, string album, string username)
|
||||
: base(auth)
|
||||
{
|
||||
Method = "album.getTags";
|
||||
|
||||
AlbumName = album;
|
||||
ArtistName = artist;
|
||||
UserName = username;
|
||||
AlbumName = album;
|
||||
Username = username;
|
||||
}
|
||||
|
||||
|
||||
public override void SetParameters()
|
||||
{
|
||||
if (AlbumMbid != null)
|
||||
{
|
||||
Parameters.Add("mbid", AlbumMbid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Parameters.Add("artist", ArtistName);
|
||||
Parameters.Add("album", AlbumName);
|
||||
Parameters.Add("user", UserName);
|
||||
}
|
||||
Parameters.Add("user", Username);
|
||||
Parameters.Add("autocorrect", Convert.ToInt32(Autocorrect).ToString());
|
||||
|
||||
AddPagingParameters();
|
||||
@ -60,14 +51,14 @@ public async override Task<PageResponse<LastTag>> HandleResponse(HttpResponseMes
|
||||
if (LastFm.IsResponseValid(json, out error) && response.IsSuccessStatusCode)
|
||||
{
|
||||
var jtoken = JsonConvert.DeserializeObject<JToken>(json);
|
||||
var resultsToken = jtoken.SelectToken("toptags");
|
||||
var resultsToken = jtoken.SelectToken("tags");
|
||||
var itemsToken = resultsToken.SelectToken("tag");
|
||||
|
||||
return PageResponse<LastTag>.CreateSuccessResponse(itemsToken, resultsToken, LastTag.ParseJToken, false);
|
||||
return PageResponse<LastTag>.CreateSuccessResponse(itemsToken, LastTag.ParseJToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LastResponse.CreateErrorResponse<PageResponse<LastTag>>(error);
|
||||
return PageResponse<LastTag>.CreateErrorResponse(error);
|
||||
}
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ public async override Task<PageResponse<LastShout>> HandleResponse(HttpResponseM
|
||||
var itemsToken = jtoken.SelectToken("shout");
|
||||
var pageInfoToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken);
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -64,7 +64,7 @@ public async override Task<PageResponse<LastTag>> HandleResponse(HttpResponseMes
|
||||
var resultsToken = jtoken.SelectToken("toptags");
|
||||
var itemsToken = resultsToken.SelectToken("tag");
|
||||
|
||||
return PageResponse<LastTag>.CreateSuccessResponse(itemsToken, resultsToken, LastTag.ParseJToken, false);
|
||||
return PageResponse<LastTag>.CreateSuccessResponse(itemsToken, resultsToken, LastTag.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ public async override Task<PageResponse<LastAlbum>> HandleResponse(HttpResponseM
|
||||
var resultsToken = jtoken.SelectToken("results");
|
||||
var itemsToken = resultsToken.SelectToken("albummatches").SelectToken("album");
|
||||
|
||||
return PageResponse<LastAlbum>.CreateSuccessResponse(itemsToken, resultsToken, LastAlbum.ParseJToken, true);
|
||||
return PageResponse<LastAlbum>.CreateSuccessResponse(itemsToken, resultsToken, LastAlbum.ParseJToken, LastPageResultsType.OpenQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ public override async Task<PageResponse<LastShout>> HandleResponse(HttpResponseM
|
||||
var itemsToken = shoutsToken.SelectToken("shout");
|
||||
var pageInfoToken = shoutsToken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken);
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ public async override Task<PageResponse<LastArtist>> HandleResponse(HttpResponse
|
||||
var jtoken = JsonConvert.DeserializeObject<JToken>(json);
|
||||
var itemsToken = jtoken.SelectToken("similarartists").SelectToken("artist");
|
||||
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, null, LastArtist.ParseJToken);
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, LastArtist.ParseJToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ public async override Task<PageResponse<LastAlbum>> HandleResponse(HttpResponseM
|
||||
var itemsToken = albumsToken.SelectToken("album");
|
||||
var pageInfoToken = albumsToken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastAlbum>.CreateSuccessResponse(itemsToken, pageInfoToken, LastAlbum.ParseJToken);
|
||||
return PageResponse<LastAlbum>.CreateSuccessResponse(itemsToken, pageInfoToken, LastAlbum.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ public async override Task<PageResponse<LastTrack>> HandleResponse(HttpResponseM
|
||||
var itemsToken = tracksToken.SelectToken("track");
|
||||
var pageInfoToken = tracksToken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, pageInfoToken, LastTrack.ParseJToken);
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, pageInfoToken, LastTrack.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ public async override Task<PageResponse<LastArtist>> HandleResponse(HttpResponse
|
||||
var resultsToken = jtoken.SelectToken("results");
|
||||
var itemsToken = resultsToken.SelectToken("artistmatches").SelectToken("artist");
|
||||
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, resultsToken, LastArtist.ParseJToken, true);
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, resultsToken, LastArtist.ParseJToken, LastPageResultsType.OpenQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ public async override Task<PageResponse<LastArtist>> HandleResponse(HttpResponse
|
||||
var itemsToken = jtoken.SelectToken("artist");
|
||||
var pageInfoToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, pageInfoToken, LastArtist.ParseJToken);
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, pageInfoToken, LastArtist.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ public async override Task<PageResponse<LastTrack>> HandleResponse(HttpResponseM
|
||||
var itemsToken = tracksToken.SelectToken("track");
|
||||
var pageInfoToken = tracksToken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, pageInfoToken, LastTrack.ParseJToken);
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, pageInfoToken, LastTrack.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ public async override Task<PageResponse<LastTrack>> HandleResponse(HttpResponseM
|
||||
var tracksToken = jtoken.SelectToken("track");
|
||||
var pageInfoToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(tracksToken, pageInfoToken, LastTrack.ParseJToken, false);
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(tracksToken, pageInfoToken, LastTrack.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ public async override Task<PageResponse<LastTrack>> HandleResponse(HttpResponseM
|
||||
var jtoken = JsonConvert.DeserializeObject<JToken>(json);
|
||||
var itemsToken = jtoken.SelectToken("similartracks").SelectToken("track");
|
||||
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, null, LastTrack.ParseJToken);
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, LastTrack.ParseJToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ public async override Task<PageResponse<LastShout>> HandleResponse(HttpResponseM
|
||||
var itemsToken = jtoken.SelectToken("shout");
|
||||
var pageInfoToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken);
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ public async override Task<PageResponse<LastTrack>> HandleResponse(HttpResponseM
|
||||
var resultsToken = jtoken.SelectToken("results");
|
||||
var itemsToken = resultsToken.SelectToken("trackmatches").SelectToken("track");
|
||||
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, resultsToken, LastTrack.ParseJToken, true);
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, resultsToken, LastTrack.ParseJToken, LastPageResultsType.OpenQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public async override Task<PageResponse<LastArtist>> HandleResponse(HttpResponse
|
||||
var resultsToken = jtoken.SelectToken("recommendations");
|
||||
var itemsToken = resultsToken.SelectToken("artist");
|
||||
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, resultsToken, LastArtist.ParseJToken, false);
|
||||
return PageResponse<LastArtist>.CreateSuccessResponse(itemsToken, resultsToken, LastArtist.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ public async override Task<PageResponse<LastAlbum>> HandleResponse(HttpResponseM
|
||||
var itemsToken = jtoken.SelectToken("topalbums").SelectToken("album");
|
||||
var pageInfoToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastAlbum>.CreateSuccessResponse(itemsToken, pageInfoToken, LastAlbum.ParseJToken);
|
||||
return PageResponse<LastAlbum>.CreateSuccessResponse(itemsToken, pageInfoToken, LastAlbum.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ public async override Task<PageResponse<LastShout>> HandleResponse(HttpResponseM
|
||||
var itemsToken = shoutsToken.SelectToken("shout");
|
||||
var pageInfoToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken);
|
||||
return PageResponse<LastShout>.CreateSuccessResponse(itemsToken, pageInfoToken, LastShout.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ public async override Task<PageResponse<LastTrack>> HandleResponse(HttpResponseM
|
||||
var itemsToken = jtoken.SelectToken("track");
|
||||
var attrToken = jtoken.SelectToken("@attr");
|
||||
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, attrToken, LastTrack.ParseJToken, false);
|
||||
return PageResponse<LastTrack>.CreateSuccessResponse(itemsToken, attrToken, LastTrack.ParseJToken, LastPageResultsType.Attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -29,4 +29,11 @@ public enum Gender
|
||||
Male,
|
||||
Female
|
||||
}
|
||||
|
||||
public enum LastPageResultsType
|
||||
{
|
||||
None = 0,
|
||||
Attr,
|
||||
OpenQuery
|
||||
}
|
||||
}
|
@ -4,7 +4,14 @@
|
||||
|
||||
namespace IF.Lastfm.Core.Api.Helpers
|
||||
{
|
||||
public class LastResponse
|
||||
public interface ILastResponse
|
||||
{
|
||||
bool Success { get; set; }
|
||||
|
||||
LastFmApiError Error { get; set; }
|
||||
}
|
||||
|
||||
public class LastResponse : ILastResponse
|
||||
{
|
||||
#region Properties
|
||||
|
||||
|
@ -1,28 +1,48 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using IF.Lastfm.Core.Api.Enums;
|
||||
using IF.Lastfm.Core.Objects;
|
||||
using IF.Lastfm.Core.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace IF.Lastfm.Core.Api.Helpers
|
||||
{
|
||||
public class PageResponse<T> : LastResponse, IEnumerable<T> where T : new()
|
||||
public interface IPageResponse<out T> : ILastResponse, IEnumerable<T> where T : new()
|
||||
{
|
||||
IReadOnlyList<T> Content { get; }
|
||||
|
||||
int Page { get; }
|
||||
|
||||
int PageSize { get; }
|
||||
|
||||
int TotalPages { get; }
|
||||
|
||||
int TotalItems { get; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(PageResponseJsonConverter))]
|
||||
public class PageResponse<T> : LastResponse, IPageResponse<T> where T : new()
|
||||
{
|
||||
private int? _totalItems;
|
||||
private int? _pageSize;
|
||||
|
||||
public PageResponse()
|
||||
public PageResponse() : this(Enumerable.Empty<T>())
|
||||
{
|
||||
}
|
||||
|
||||
public PageResponse(IEnumerable<T> content)
|
||||
{
|
||||
Page = 1;
|
||||
TotalPages = 1;
|
||||
Content = new List<T>();
|
||||
Content = new ReadOnlyCollection<T>(content.ToList());
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public List<T> Content { get; internal set; }
|
||||
public IReadOnlyList<T> Content { get; internal set; }
|
||||
|
||||
public int Page { get; internal set; }
|
||||
|
||||
@ -46,14 +66,9 @@ public int PageSize
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
if (Content != null)
|
||||
{
|
||||
return Content.GetEnumerator();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Content != null
|
||||
? Content.GetEnumerator()
|
||||
: null;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
@ -72,6 +87,20 @@ IEnumerator IEnumerable.GetEnumerator()
|
||||
|
||||
#region Factory methods
|
||||
|
||||
public static PageResponse<T> CreateErrorResponse(LastFmApiError error)
|
||||
{
|
||||
var r = new PageResponse<T>
|
||||
{
|
||||
Success = false,
|
||||
Error = error
|
||||
};
|
||||
|
||||
r.AddDefaultPageInfo();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public new static PageResponse<T> CreateSuccessResponse()
|
||||
{
|
||||
var r = new PageResponse<T>
|
||||
@ -80,71 +109,86 @@ IEnumerator IEnumerable.GetEnumerator()
|
||||
Error = LastFmApiError.None
|
||||
};
|
||||
|
||||
r.AddDefaultPageInfo();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public static PageResponse<T> CreateSuccessResponse(IEnumerable<T> content)
|
||||
{
|
||||
var r = new PageResponse<T>
|
||||
var r = new PageResponse<T>(content)
|
||||
{
|
||||
Success = true,
|
||||
Error = LastFmApiError.None
|
||||
};
|
||||
|
||||
r.Content.AddRange(content);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public static PageResponse<T> CreateSuccessResponse(JToken itemsToken, JToken pageInfoToken, Func<JToken, T> parseToken, bool isOpenQueryToken = false)
|
||||
public static PageResponse<T> CreateSuccessResponse(JToken itemsToken, Func<JToken, T> parseToken)
|
||||
{
|
||||
var pageresponse = CreateSuccessResponse();
|
||||
return CreateSuccessResponse(itemsToken, null, parseToken, LastPageResultsType.None);
|
||||
}
|
||||
|
||||
public static PageResponse<T> CreateSuccessResponse(JToken itemsToken, JToken pageInfoToken, Func<JToken, T> parseToken, LastPageResultsType pageResultsType)
|
||||
{
|
||||
IEnumerable<T> items;
|
||||
if (itemsToken != null && itemsToken.Children().Any())
|
||||
{
|
||||
// array notation isn't used on the api when only one object is available
|
||||
if (itemsToken.Type != JTokenType.Array)
|
||||
{
|
||||
var item = parseToken(itemsToken);
|
||||
pageresponse.Content.Add(item);
|
||||
items = new[] {item};
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var items = itemsToken.Children().Select(parseToken);
|
||||
pageresponse.Content.AddRange(items);
|
||||
items = itemsToken.Children().Select(parseToken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
items = Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
if (pageInfoToken != null)
|
||||
{
|
||||
if (isOpenQueryToken)
|
||||
{
|
||||
pageresponse.AddPageInfoFromOpenQueryJToken(pageInfoToken);
|
||||
}
|
||||
else
|
||||
var pageresponse = new PageResponse<T>(items);
|
||||
|
||||
switch (pageResultsType)
|
||||
{
|
||||
case LastPageResultsType.Attr:
|
||||
pageresponse.AddPageInfoFromJToken(pageInfoToken);
|
||||
break;
|
||||
case LastPageResultsType.OpenQuery:
|
||||
pageresponse.AddPageInfoFromOpenQueryJToken(pageInfoToken);
|
||||
break;
|
||||
case LastPageResultsType.None:
|
||||
default:
|
||||
pageresponse.AddDefaultPageInfo(pageresponse.Content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pageresponse.AddDefaultPageInfo(pageresponse.Content.Count);
|
||||
}
|
||||
|
||||
pageresponse.Success = true;
|
||||
|
||||
return pageresponse;
|
||||
}
|
||||
|
||||
private void AddDefaultPageInfo(int count)
|
||||
#endregion
|
||||
|
||||
private void AddDefaultPageInfo()
|
||||
{
|
||||
AddDefaultPageInfo(Enumerable.Empty<T>().ToList());
|
||||
}
|
||||
|
||||
private void AddDefaultPageInfo(IReadOnlyCollection<T> items)
|
||||
{
|
||||
Page = 1;
|
||||
TotalPages = 1;
|
||||
TotalItems = count;
|
||||
PageSize = count;
|
||||
TotalItems = items.Count;
|
||||
PageSize = items.Count;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal void AddPageInfoFromJToken(JToken attrToken)
|
||||
{
|
||||
if (attrToken == null)
|
||||
|
@ -12,12 +12,12 @@ public interface IAlbumApi
|
||||
|
||||
Task<LastResponse<LastAlbum>> GetAlbumInfoByMbidAsync(string albumMbid, bool autocorrect = false);
|
||||
|
||||
Task<PageResponse<BuyLink>> GetBuyLinksForAlbumAsync(string artist,
|
||||
string album,
|
||||
CountryCode country,
|
||||
bool autocorrect = false);
|
||||
//Task<PageResponse<BuyLink>> GetBuyLinksForAlbumAsync(string artist,
|
||||
// string album,
|
||||
// CountryCode country,
|
||||
// bool autocorrect = false);
|
||||
|
||||
Task<PageResponse<LastTag>> GetUserTagsForAlbumAsync(string artist,
|
||||
Task<PageResponse<LastTag>> GetTagsByUserAsync(string artist,
|
||||
string album,
|
||||
string username,
|
||||
bool autocorrect = false);
|
||||
|
@ -41,7 +41,7 @@
|
||||
<Compile Include="Api\AlbumApi.cs" />
|
||||
<Compile Include="Api\ArtistApi.cs" />
|
||||
<Compile Include="Api\Commands\AlbumApi\GetAlbumTopTagsCommand.cs" />
|
||||
<Compile Include="Api\Commands\AlbumApi\GetUserTagsForAlbumCommand.cs" />
|
||||
<Compile Include="Api\Commands\AlbumApi\AlbumGetTagsByUserCommand.cs" />
|
||||
<Compile Include="Api\Commands\LibraryApi\LibraryGetTracksCommand.cs" />
|
||||
<Compile Include="Api\Commands\TrackApi\TrackScrobbleCommand.cs" />
|
||||
<Compile Include="Api\Commands\TrackApi\TrackUpdateNowPlayingCommand.cs" />
|
||||
@ -99,6 +99,7 @@
|
||||
<Compile Include="Api\TrackApi.cs" />
|
||||
<Compile Include="Api\UserApi.cs" />
|
||||
<Compile Include="Json\LastFmBooleanConverter.cs" />
|
||||
<Compile Include="Json\PageResponseJsonConverter.cs" />
|
||||
<Compile Include="LastFm.cs" />
|
||||
<Compile Include="MD5.cs" />
|
||||
<Compile Include="Objects\LastAlbum.cs" />
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace IF.Lastfm.Core.Json
|
||||
{
|
||||
|
39
src/IF.Lastfm.Core/Json/PageResponseJsonConverter.cs
Normal file
39
src/IF.Lastfm.Core/Json/PageResponseJsonConverter.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using IF.Lastfm.Core.Api.Helpers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace IF.Lastfm.Core.Json
|
||||
{
|
||||
public class PageResponseJsonConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var pageResponse = (IPageResponse<object>) value;
|
||||
|
||||
dynamic container = new
|
||||
{
|
||||
success = pageResponse.Success,
|
||||
items = pageResponse.Content,
|
||||
page = new
|
||||
{
|
||||
totalItems = pageResponse.TotalItems,
|
||||
pageSize = pageResponse.PageSize,
|
||||
page = pageResponse.Page,
|
||||
totalPages = pageResponse.TotalPages
|
||||
}
|
||||
};
|
||||
|
||||
serializer.Serialize(writer, container);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
return serializer.Deserialize(reader, objectType);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof (PageResponse<>);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user