From a70bc5fc0965b3bcd76f30697bd2cdda0c662b53 Mon Sep 17 00:00:00 2001 From: Philipp Drebes Date: Thu, 9 Nov 2017 15:36:53 +0100 Subject: [PATCH] Refactored SpotifyUri Parsing (#194) * refactored SpotifyUri parsing * unit tests for SpotifyUri class * added missing file reference in SpotifyAPI.csproj * updated NuGet packages in SpotifyAPI.Tests and reverted inline TryParse variable declarations in SpotifyUri.cs --- .gitignore | 1 + SpotifyAPI.Tests/SpotifyAPI.Tests.csproj | 25 ++++++---- SpotifyAPI.Tests/SpotifyUriTest.cs | 59 ++++++++++++++++++++++++ SpotifyAPI.Tests/packages.config | 7 +-- SpotifyAPI/Local/Enums/UriType.cs | 12 +++++ SpotifyAPI/Local/Models/SpotifyUri.cs | 45 ++++++++++++++---- SpotifyAPI/SpotifyAPI.csproj | 6 +-- SpotifyAPI/packages.config | 2 +- 8 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 SpotifyAPI.Tests/SpotifyUriTest.cs create mode 100644 SpotifyAPI/Local/Enums/UriType.cs diff --git a/.gitignore b/.gitignore index ece5322e..45a0df12 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ TestResults *.suo *.user *.sln.docstates +.vs/ # Build results [Dd]ebug/ diff --git a/SpotifyAPI.Tests/SpotifyAPI.Tests.csproj b/SpotifyAPI.Tests/SpotifyAPI.Tests.csproj index 4fe1ea5d..492155bd 100644 --- a/SpotifyAPI.Tests/SpotifyAPI.Tests.csproj +++ b/SpotifyAPI.Tests/SpotifyAPI.Tests.csproj @@ -32,19 +32,20 @@ 4 - - ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll - True + + ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll - - ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll - True + + ..\packages\Moq.4.7.145\lib\net45\Moq.dll - - ..\packages\NUnit.3.0.0\lib\net45\nunit.framework.dll - True + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll + @@ -53,6 +54,7 @@ + @@ -67,6 +69,9 @@ + + + - + \ No newline at end of file diff --git a/SpotifyAPI.Tests/SpotifyUriTest.cs b/SpotifyAPI.Tests/SpotifyUriTest.cs new file mode 100644 index 00000000..395173a3 --- /dev/null +++ b/SpotifyAPI.Tests/SpotifyUriTest.cs @@ -0,0 +1,59 @@ +using Moq; +using Newtonsoft.Json; +using NUnit.Framework; +using SpotifyAPI.Local; +using SpotifyAPI.Local.Models; +using SpotifyAPI.Local.Enums; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace SpotifyAPI.Tests +{ + public class SpotifyUriTest + { + [Test] + public void ShouldThrowArgumentExceptionForInvalidUri() + { + Assert.Throws(() => SpotifyUri.Parse("asdafadfgsrsegqejfa")); + } + + [Test] + public void ShouldCorrectlyParseTrackUri() + { + string testUri = "spotify:track:3QOruXa2lvqIFvOOa2rYyJ"; + SpotifyUri uri = SpotifyUri.Parse(testUri); + + Assert.AreEqual(uri.Base, "spotify"); + + Assert.AreEqual(uri.Type, UriType.track); + Assert.AreEqual(uri.Id, "3QOruXa2lvqIFvOOa2rYyJ"); + Assert.AreEqual(uri.ToString(), testUri); + } + + [Test] + public void ShouldCorrectlyParsePlaylistUri() + { + string testUri = "spotify:user:spotifycharts:playlist:37i9dQZEVXbMDoHDwVN2tF"; + SpotifyUri uri = SpotifyUri.Parse(testUri); + + Assert.AreEqual(uri.Base, "spotify"); + + Assert.AreEqual(uri.Type, UriType.playlist); + Assert.AreEqual(uri.Id, "37i9dQZEVXbMDoHDwVN2tF"); + + Assert.AreEqual(uri.GetUriPropValue(UriType.user), "spotifycharts"); + Assert.AreEqual(uri.ToString(), testUri); + } + + [Test] + public void ShouldHandleNotExistingUriProperty() + { + string testUri = "spotify:track:3QOruXa2lvqIFvOOa2rYyJ"; + SpotifyUri uri = SpotifyUri.Parse(testUri); + Assert.DoesNotThrow(() => uri.GetUriPropValue(UriType.user)); + Assert.IsNull(uri.GetUriPropValue(UriType.user)); + } + } +} \ No newline at end of file diff --git a/SpotifyAPI.Tests/packages.config b/SpotifyAPI.Tests/packages.config index f388c034..1b3f7008 100644 --- a/SpotifyAPI.Tests/packages.config +++ b/SpotifyAPI.Tests/packages.config @@ -1,6 +1,7 @@  - - - + + + + \ No newline at end of file diff --git a/SpotifyAPI/Local/Enums/UriType.cs b/SpotifyAPI/Local/Enums/UriType.cs new file mode 100644 index 00000000..c5170755 --- /dev/null +++ b/SpotifyAPI/Local/Enums/UriType.cs @@ -0,0 +1,12 @@ +namespace SpotifyAPI.Local.Enums +{ + public enum UriType + { + none, + track, + album, + artist, + playlist, + user + } +} \ No newline at end of file diff --git a/SpotifyAPI/Local/Models/SpotifyUri.cs b/SpotifyAPI/Local/Models/SpotifyUri.cs index 936ff0f9..7b4f6e43 100644 --- a/SpotifyAPI/Local/Models/SpotifyUri.cs +++ b/SpotifyAPI/Local/Models/SpotifyUri.cs @@ -1,4 +1,5 @@ -using System; +using SpotifyAPI.Local.Enums; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,15 +9,29 @@ namespace SpotifyAPI.Local.Models { public class SpotifyUri { - public string Base { get; internal set; } - public string Type { get; internal set; } - public string Id { get; internal set; } + internal Dictionary _properties = new Dictionary(); - public SpotifyUri(string uriBase, string uriType, string uriId) + public string Base { get; internal set; } + public UriType Type => _properties?.LastOrDefault().Key ?? UriType.none; + public string Id => _properties?.LastOrDefault().Value; + + public SpotifyUri(string uriBase, Dictionary properties) { Base = uriBase; - Type = uriType; - Id = uriId; + _properties = properties; + } + + public SpotifyUri(string uriBase, UriType uriType, string uriId) + { + Base = uriBase; + _properties.Add(uriType, uriId); + } + + public string GetUriPropValue(UriType type) + { + if (!_properties.ContainsKey(type)) + return null; + return _properties[type]; } public static SpotifyUri Parse(string uri) @@ -24,16 +39,26 @@ namespace SpotifyAPI.Local.Models if (string.IsNullOrEmpty(uri)) throw new ArgumentNullException("Uri"); + UriType uriType = UriType.none; string[] props = uri.Split(':'); - if (props.Length != 3) + if (props.Length < 3 || !Enum.TryParse(props[1], out uriType)) throw new ArgumentException("Unexpected Uri"); - return new SpotifyUri(props[0], props[1], props[2]); + Dictionary properties = new Dictionary { { uriType, props[2] } }; + + for (int index = 3; index < props.Length; index += 2) + { + UriType type = UriType.none; + if (Enum.TryParse(props[index], out type)) + properties.Add(type, props[index + 1]); + } + + return new SpotifyUri(props[0], properties); } public override string ToString() { - return $"{Base}:{Type}:{Id}"; + return $"{Base}:{string.Join(":", _properties.SelectMany(x => new string[] { x.Key.ToString(), x.Value }))}"; } } } diff --git a/SpotifyAPI/SpotifyAPI.csproj b/SpotifyAPI/SpotifyAPI.csproj index 9462a5d4..f7ca413e 100644 --- a/SpotifyAPI/SpotifyAPI.csproj +++ b/SpotifyAPI/SpotifyAPI.csproj @@ -37,9 +37,8 @@ 1591 - - ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll - True + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll @@ -55,6 +54,7 @@ + Component diff --git a/SpotifyAPI/packages.config b/SpotifyAPI/packages.config index 2abc396b..ee51c237 100644 --- a/SpotifyAPI/packages.config +++ b/SpotifyAPI/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file