diff --git a/PlexRequests.Core/SettingModels/PlexRequestSettings.cs b/PlexRequests.Core/SettingModels/PlexRequestSettings.cs
index 493d8bf39..4e986c555 100644
--- a/PlexRequests.Core/SettingModels/PlexRequestSettings.cs
+++ b/PlexRequests.Core/SettingModels/PlexRequestSettings.cs
@@ -1,77 +1,78 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: PlexRequestSettings.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-
-namespace PlexRequests.Core.SettingModels
-{
- public class PlexRequestSettings : Settings
- {
- public int Port { get; set; }
- public string BaseUrl { get; set; }
- public bool SearchForMovies { get; set; }
- public bool SearchForTvShows { get; set; }
- public bool SearchForMusic { get; set; }
- public bool RequireMovieApproval { get; set; }
- public bool RequireTvShowApproval { get; set; }
- public bool RequireMusicApproval { get; set; }
- public bool UsersCanViewOnlyOwnRequests { get; set; }
- public bool UsersCanViewOnlyOwnIssues { get; set; }
- public int WeeklyRequestLimit { get; set; }
- public string NoApprovalUsers { get; set; }
- public bool CollectAnalyticData { get; set; }
-
- ///
- /// The CSS name of the theme we want
- ///
- public string ThemeName { get; set; }
-
- public string ApiKey { get; set; }
-
- [JsonIgnore]
- public List ApprovalWhiteList
- {
- get
- {
- var users = new List();
- if (string.IsNullOrEmpty(NoApprovalUsers))
- {
- return users;
- }
-
- var splitUsers = NoApprovalUsers.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- foreach (var user in splitUsers)
- {
- if (!string.IsNullOrWhiteSpace(user))
- users.Add(user.Trim());
- }
- return users;
- }
- }
- }
-}
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: PlexRequestSettings.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+
+namespace PlexRequests.Core.SettingModels
+{
+ public class PlexRequestSettings : Settings
+ {
+ public int Port { get; set; }
+ public string BaseUrl { get; set; }
+ public bool SearchForMovies { get; set; }
+ public bool SearchForTvShows { get; set; }
+ public bool SearchForMusic { get; set; }
+ public bool RequireMovieApproval { get; set; }
+ public bool RequireTvShowApproval { get; set; }
+ public bool RequireMusicApproval { get; set; }
+ public bool UsersCanViewOnlyOwnRequests { get; set; }
+ public bool UsersCanViewOnlyOwnIssues { get; set; }
+ public int WeeklyRequestLimit { get; set; }
+ public string NoApprovalUsers { get; set; }
+ public bool CollectAnalyticData { get; set; }
+ public bool IgnoreNotifyForAutoApprovedRequests { get; set; }
+
+ ///
+ /// The CSS name of the theme we want
+ ///
+ public string ThemeName { get; set; }
+
+ public string ApiKey { get; set; }
+
+ [JsonIgnore]
+ public List ApprovalWhiteList
+ {
+ get
+ {
+ var users = new List();
+ if (string.IsNullOrEmpty(NoApprovalUsers))
+ {
+ return users;
+ }
+
+ var splitUsers = NoApprovalUsers.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var user in splitUsers)
+ {
+ if (!string.IsNullOrWhiteSpace(user))
+ users.Add(user.Trim());
+ }
+ return users;
+ }
+ }
+ }
+}
diff --git a/PlexRequests.Core/Setup.cs b/PlexRequests.Core/Setup.cs
index 85a72d7f9..e66a15cec 100644
--- a/PlexRequests.Core/Setup.cs
+++ b/PlexRequests.Core/Setup.cs
@@ -57,10 +57,6 @@ public string SetupDb(string urlBase)
var version = CheckSchema();
if (version > 0)
{
- if (version > 1700 && version <= 1799)
- {
- MigrateToVersion1700();
- }
if (version > 1799 && version <= 1800)
{
MigrateToVersion1800();
diff --git a/PlexRequests.Helpers.Tests/CookieHelperTests.cs b/PlexRequests.Helpers.Tests/CookieHelperTests.cs
new file mode 100644
index 000000000..c9a8205fb
--- /dev/null
+++ b/PlexRequests.Helpers.Tests/CookieHelperTests.cs
@@ -0,0 +1,52 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: DateTimeHelperTests.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using System.Collections.Generic;
+
+using NUnit.Framework;
+
+namespace PlexRequests.Helpers.Tests
+{
+ [TestFixture]
+ public class CookieHelperTests
+ {
+ [TestCaseSource(nameof(GetAnalyticsClientId))]
+ public string TestGetAnalyticsClientId(Dictionary cookies)
+ {
+ return CookieHelper.GetAnalyticClientId(cookies);
+ }
+
+ private static IEnumerable GetAnalyticsClientId
+ {
+ get
+ {
+ yield return new TestCaseData(new Dictionary()).Returns(string.Empty);
+ yield return new TestCaseData(new Dictionary { { "_ga", "GA1.1.306549087.1464005217" } }).Returns("306549087.1464005217");
+ yield return new TestCaseData(new Dictionary { {"_ga", "GA1.1.306549087" } }).Returns(string.Empty);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj b/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj
index 308e966e7..0789e013c 100644
--- a/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj
+++ b/PlexRequests.Helpers.Tests/PlexRequests.Helpers.Tests.csproj
@@ -1,119 +1,120 @@
-
-
-
- Debug
- AnyCPU
- {0E6395D3-B074-49E8-898D-0EB99E507E0E}
- Library
- Properties
- PlexRequests.Helpers.Tests
- PlexRequests.Helpers.Tests
- v4.5
- 512
- {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
- $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
- False
- UnitTest
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
- True
-
-
- ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
- True
-
-
- ..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll
- True
-
-
- ..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {1252336d-42a3-482a-804c-836e60173dfa}
- PlexRequests.Helpers
-
-
-
-
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
-
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ {0E6395D3-B074-49E8-898D-0EB99E507E0E}
+ Library
+ Properties
+ PlexRequests.Helpers.Tests
+ PlexRequests.Helpers.Tests
+ v4.5
+ 512
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 10.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
+ False
+ UnitTest
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
+ True
+
+
+ ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
+ True
+
+
+ ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+ ..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll
+ True
+
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {1252336d-42a3-482a-804c-836e60173dfa}
+ PlexRequests.Helpers
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PlexRequests.Helpers/Analytics/Action.cs b/PlexRequests.Helpers/Analytics/Action.cs
index a353dcc33..4a42a45be 100644
--- a/PlexRequests.Helpers/Analytics/Action.cs
+++ b/PlexRequests.Helpers/Analytics/Action.cs
@@ -34,6 +34,7 @@ public enum Action
Create,
Save,
Update,
- Start
+ Start,
+ View
}
}
\ No newline at end of file
diff --git a/PlexRequests.Helpers/Analytics/Analytics.cs b/PlexRequests.Helpers/Analytics/Analytics.cs
index 4b4d74ed9..764295fa3 100644
--- a/PlexRequests.Helpers/Analytics/Analytics.cs
+++ b/PlexRequests.Helpers/Analytics/Analytics.cs
@@ -47,52 +47,51 @@ public class Analytics : IAnalytics
private static Logger Log = LogManager.GetCurrentClassLogger();
- public void TrackEvent(Category category, Action action, string label, string username, int? value = null)
+ public void TrackEvent(Category category, Action action, string label, string username, string clientId, int? value = null)
{
var cat = category.ToString();
var act = action.ToString();
- Track(HitType.@event, username, cat, act, label, value);
+ Track(HitType.@event, username, cat, act, label, clientId, value);
}
- public async Task TrackEventAsync(Category category, Action action, string label, string username, int? value = null)
+ public async Task TrackEventAsync(Category category, Action action, string label, string username, string clientId, int? value = null)
{
var cat = category.ToString();
var act = action.ToString();
- await TrackAsync(HitType.@event, username, cat, act, label, value);
+ await TrackAsync(HitType.@event, username, cat, act, clientId, label, value);
}
- public void TrackPageview(Category category, Action action, string label, string username, int? value = null)
+ public void TrackPageview(Category category, Action action, string label, string username, string clientId, int? value = null)
{
var cat = category.ToString();
var act = action.ToString();
- Track(HitType.@pageview, username, cat, act, label, value);
+ Track(HitType.@pageview, username, cat, act, clientId, label, value);
}
- public async Task TrackPageviewAsync(Category category, Action action, string label, string username, int? value = null)
+ public async Task TrackPageviewAsync(Category category, Action action, string label, string username, string clientId, int? value = null)
{
var cat = category.ToString();
var act = action.ToString();
- await TrackAsync(HitType.@pageview, username, cat, act, label, value);
+ await TrackAsync(HitType.@pageview, username, cat, act, clientId, label, value);
}
- public void TrackException(string message, string username, bool fatal)
+ public void TrackException(string message, string username, string clientId, bool fatal)
{
var fatalInt = fatal ? 1 : 0;
- Track(HitType.exception, message, fatalInt, username);
+ Track(HitType.exception, message, fatalInt, username, clientId);
}
- public async Task TrackExceptionAsync(string message, string username, bool fatal)
+ public async Task TrackExceptionAsync(string message, string username, string clientId, bool fatal)
{
var fatalInt = fatal ? 1 : 0;
- await TrackAsync(HitType.exception, message, fatalInt, username);
+ await TrackAsync(HitType.exception, message, fatalInt, username, clientId);
}
- private void Track(HitType type, string username, string category, string action, string label, int? value = null)
+ private void Track(HitType type, string username, string category, string action, string clientId, string label, int? value = null)
{
if (string.IsNullOrEmpty(category)) throw new ArgumentNullException(nameof(category));
if (string.IsNullOrEmpty(action)) throw new ArgumentNullException(nameof(action));
- if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
- var postData = BuildRequestData(type, username, category, action, label, value, null, null);
+ var postData = BuildRequestData(type, username, category, action, clientId, label, value, null, null);
var postDataString = postData
.Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}"))
@@ -101,13 +100,12 @@ private void Track(HitType type, string username, string category, string action
SendRequest(postDataString);
}
- private async Task TrackAsync(HitType type, string username, string category, string action, string label, int? value = null)
+ private async Task TrackAsync(HitType type, string username, string category, string action, string clientId, string label, int? value = null)
{
if (string.IsNullOrEmpty(category)) throw new ArgumentNullException(nameof(category));
if (string.IsNullOrEmpty(action)) throw new ArgumentNullException(nameof(action));
- if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
- var postData = BuildRequestData(type, username, category, action, label, value, null, null);
+ var postData = BuildRequestData(type, username, category, action, clientId, label, value, null, null);
var postDataString = postData
.Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}"))
@@ -115,12 +113,11 @@ private async Task TrackAsync(HitType type, string username, string category, st
await SendRequestAsync(postDataString);
}
- private async Task TrackAsync(HitType type, string message, int fatal, string username)
+ private async Task TrackAsync(HitType type, string message, int fatal, string username, string clientId)
{
if (string.IsNullOrEmpty(message)) throw new ArgumentNullException(nameof(message));
- if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
- var postData = BuildRequestData(type, username, null, null, null, null, message, fatal);
+ var postData = BuildRequestData(type, username, null, null, null, clientId, null, message, fatal);
var postDataString = postData
.Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}"))
@@ -129,12 +126,12 @@ private async Task TrackAsync(HitType type, string message, int fatal, string us
await SendRequestAsync(postDataString);
}
- private void Track(HitType type, string message, int fatal, string username)
+ private void Track(HitType type, string message, int fatal, string username, string clientId)
{
if (string.IsNullOrEmpty(message)) throw new ArgumentNullException(nameof(message));
if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
- var postData = BuildRequestData(type, username, null, null, null, null, message, fatal);
+ var postData = BuildRequestData(type, username, null, null, null, clientId, null, message, fatal);
var postDataString = postData
.Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}"))
@@ -196,20 +193,24 @@ private async Task SendRequestAsync(string postDataString)
}
}
- private Dictionary BuildRequestData(HitType type, string username, string category, string action, string label, int? value, string exceptionDescription, int? fatal)
+ private Dictionary BuildRequestData(HitType type, string username, string category, string action, string clientId, string label, int? value, string exceptionDescription, int? fatal)
{
var postData = new Dictionary
{
{ "v", "1" },
{ "tid", TrackingId },
- { "t", type.ToString() },
- {"cid", Guid.NewGuid().ToString() }
+ { "t", type.ToString() }
};
if (!string.IsNullOrEmpty(username))
{
postData.Add("uid", username);
}
+
+ postData.Add("cid", !string.IsNullOrEmpty(clientId)
+ ? clientId
+ : Guid.NewGuid().ToString());
+
if (!string.IsNullOrEmpty(label))
{
postData.Add("el", label);
diff --git a/PlexRequests.Helpers/Analytics/IAnalytics.cs b/PlexRequests.Helpers/Analytics/IAnalytics.cs
index 4e228f545..d21dd18d1 100644
--- a/PlexRequests.Helpers/Analytics/IAnalytics.cs
+++ b/PlexRequests.Helpers/Analytics/IAnalytics.cs
@@ -37,8 +37,9 @@ public interface IAnalytics
/// The action.
/// The label.
/// The username.
+ /// The client identifier.
/// The value.
- void TrackEvent(Category category, Action action, string label, string username, int? value = null);
+ void TrackEvent(Category category, Action action, string label, string username, string clientId, int? value = null);
///
/// Tracks the event asynchronous.
@@ -47,9 +48,10 @@ public interface IAnalytics
/// The action.
/// The label.
/// The username.
+ /// The client identifier.
/// The value.
///
- Task TrackEventAsync(Category category, Action action, string label, string username, int? value = null);
+ Task TrackEventAsync(Category category, Action action, string label, string username, string clientId, int? value = null);
///
/// Tracks the page view.
@@ -58,8 +60,9 @@ public interface IAnalytics
/// The action.
/// The label.
/// The username.
+ /// The client identifier.
/// The value.
- void TrackPageview(Category category, Action action, string label, string username, int? value = null);
+ void TrackPageview(Category category, Action action, string label, string username, string clientId, int? value = null);
///
/// Tracks the page view asynchronous.
@@ -68,25 +71,28 @@ public interface IAnalytics
/// The action.
/// The label.
/// The username.
+ /// The client identifier.
/// The value.
///
- Task TrackPageviewAsync(Category category, Action action, string label, string username, int? value = null);
+ Task TrackPageviewAsync(Category category, Action action, string label, string username, string clientId, int? value = null);
///
/// Tracks the exception.
///
/// The message.
/// The username.
+ /// The client identifier.
/// if set to true [fatal].
- void TrackException(string message, string username, bool fatal);
+ void TrackException(string message, string username, string clientId, bool fatal);
///
/// Tracks the exception asynchronous.
///
/// The message.
/// The username.
+ /// The client identifier.
/// if set to true [fatal].
///
- Task TrackExceptionAsync(string message, string username, bool fatal);
+ Task TrackExceptionAsync(string message, string username, string clientId, bool fatal);
}
}
\ No newline at end of file
diff --git a/PlexRequests.Helpers/CookieHelper.cs b/PlexRequests.Helpers/CookieHelper.cs
new file mode 100644
index 000000000..5d4b97a60
--- /dev/null
+++ b/PlexRequests.Helpers/CookieHelper.cs
@@ -0,0 +1,57 @@
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: CookieHelper.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using System;
+using System.Collections.Generic;
+
+namespace PlexRequests.Helpers
+{
+ public static class CookieHelper
+ {
+ private const string GaCookie = "_ga";
+
+ ///
+ /// Gets the analytic client identifier.
+ /// Example: Value = "GA1.1.306549087.1464005217"
+ ///
+ /// The cookies.
+ ///
+ public static string GetAnalyticClientId(IDictionary cookies)
+ {
+ var outString = string.Empty;
+
+ if (cookies.TryGetValue(GaCookie, out outString))
+ {
+ var split = outString.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
+
+ return split.Length < 4
+ ? string.Empty
+ : $"{split[2]}.{split[3]}";
+ }
+ return string.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PlexRequests.Helpers/PlexRequests.Helpers.csproj b/PlexRequests.Helpers/PlexRequests.Helpers.csproj
index 8bdfb5ed8..df0ffcf77 100644
--- a/PlexRequests.Helpers/PlexRequests.Helpers.csproj
+++ b/PlexRequests.Helpers/PlexRequests.Helpers.csproj
@@ -1,102 +1,103 @@
-
-
-
-
- Debug
- AnyCPU
- {1252336D-42A3-482A-804C-836E60173DFA}
- Library
- Properties
- PlexRequests.Helpers
- PlexRequests.Helpers
- v4.5
- 512
-
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
- ..\packages\Hangfire.Core.1.5.7\lib\net45\Hangfire.Core.dll
- True
-
-
- ..\packages\Nancy.1.4.3\lib\net40\Nancy.dll
- True
-
-
- ..\packages\NLog.4.3.4\lib\net45\NLog.dll
- True
-
-
- ..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
- ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ AnyCPU
+ {1252336D-42A3-482A-804C-836E60173DFA}
+ Library
+ Properties
+ PlexRequests.Helpers
+ PlexRequests.Helpers
+ v4.5
+ 512
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Hangfire.Core.1.5.7\lib\net45\Hangfire.Core.dll
+ True
+
+
+ ..\packages\Nancy.1.4.3\lib\net40\Nancy.dll
+ True
+
+
+ ..\packages\NLog.4.3.4\lib\net45\NLog.dll
+ True
+
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs
index 253ba7af3..68b8da01b 100644
--- a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs
+++ b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs
@@ -179,7 +179,8 @@ public bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year,
{
if (advanced)
{
- if (movie.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase))
+ if (!string.IsNullOrEmpty(movie.ProviderId) &&
+ movie.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
diff --git a/PlexRequests.Services/Notification/EmailMessageNotification.cs b/PlexRequests.Services/Notification/EmailMessageNotification.cs
index 20ef3f612..466ff7a24 100644
--- a/PlexRequests.Services/Notification/EmailMessageNotification.cs
+++ b/PlexRequests.Services/Notification/EmailMessageNotification.cs
@@ -1,201 +1,202 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: EmailMessageNotification.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using System;
-using System.Threading.Tasks;
-
-using MailKit.Security;
-
-using MimeKit;
-using NLog;
-
-using PlexRequests.Core;
-using PlexRequests.Core.SettingModels;
-using PlexRequests.Services.Interfaces;
-using SmtpClient = MailKit.Net.Smtp.SmtpClient;
-
-namespace PlexRequests.Services.Notification
-{
- public class EmailMessageNotification : INotification
- {
- public EmailMessageNotification(ISettingsService settings)
- {
- EmailNotificationSettings = settings;
- }
-
- private static readonly Logger Log = LogManager.GetCurrentClassLogger();
- private ISettingsService EmailNotificationSettings { get; }
- public string NotificationName => "EmailMessageNotification";
-
- public async Task NotifyAsync(NotificationModel model)
- {
- var configuration = GetConfiguration();
- await NotifyAsync(model, configuration);
- }
-
- public async Task NotifyAsync(NotificationModel model, Settings settings)
- {
- if (settings == null) await NotifyAsync(model);
-
- var emailSettings = (EmailNotificationSettings)settings;
-
- if (!ValidateConfiguration(emailSettings))
- {
- return;
- }
-
- switch (model.NotificationType)
- {
- case NotificationType.NewRequest:
- await EmailNewRequest(model, emailSettings);
- break;
- case NotificationType.Issue:
- await EmailIssue(model, emailSettings);
- break;
- case NotificationType.RequestAvailable:
- await EmailAvailableRequest(model, emailSettings);
- break;
- case NotificationType.RequestApproved:
- throw new NotImplementedException();
-
- case NotificationType.AdminNote:
- throw new NotImplementedException();
-
- case NotificationType.Test:
- await EmailTest(model, emailSettings);
- break;
- }
-
- }
-
- private EmailNotificationSettings GetConfiguration()
- {
- var settings = EmailNotificationSettings.GetSettings();
- return settings;
- }
-
- private bool ValidateConfiguration(EmailNotificationSettings settings)
- {
- if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString()))
- {
- return false;
- }
-
- if (!settings.EnableUserEmailNotifications)
- {
- if (!settings.Enabled)
- {
- return false;
- }
- }
-
- return true;
- }
-
- private async Task EmailNewRequest(NotificationModel model, EmailNotificationSettings settings)
- {
- var message = new MimeMessage
- {
- Body = new TextPart("plain") { Text = $"Hello! The user '{model.User}' has requested {model.Title}! Please log in to approve this request. Request Date: {model.DateTime.ToString("f")}" },
- Subject = $"Plex Requests: New request for {model.Title}!"
- };
- message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
- message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
-
-
- await Send(message, settings);
- }
-
- private async Task EmailIssue(NotificationModel model, EmailNotificationSettings settings)
- {
- var message = new MimeMessage
- {
- Body = new TextPart("plain") { Text = $"Hello! The user '{model.User}' has reported a new issue {model.Body} for the title {model.Title}!" },
- Subject = $"Plex Requests: New issue for {model.Title}!"
- };
- message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
- message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
-
-
- await Send(message, settings);
- }
-
- private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings)
- {
- if (!settings.EnableUserEmailNotifications)
- {
- await Task.FromResult(false);
- }
-
- var message = new MimeMessage
- {
- Body = new TextPart("plain") { Text = $"Hello! You requested {model.Title} on PlexRequests! This is now available on Plex! :)" },
- Subject = $"Plex Requests: {model.Title} is now available!"
- };
- message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
- message.To.Add(new MailboxAddress(model.UserEmail, model.UserEmail));
-
- await Send(message, settings);
- }
-
- private async Task Send(MimeMessage message, EmailNotificationSettings settings)
- {
- try
- {
- using (var client = new SmtpClient())
- {
- client.Connect(settings.EmailHost, settings.EmailPort, SecureSocketOptions.Auto); // Let MailKit figure out the correct SecureSocketOptions.
-
- // Note: since we don't have an OAuth2 token, disable
- // the XOAUTH2 authentication mechanism.
- client.AuthenticationMechanisms.Remove("XOAUTH2");
-
- client.Authenticate(settings.EmailUsername, settings.EmailPassword);
-
- await client.SendAsync(message);
- await client.DisconnectAsync(true);
- }
- }
- catch (Exception e)
- {
- Log.Error(e);
- }
- }
-
- private async Task EmailTest(NotificationModel model, EmailNotificationSettings settings)
- {
- var message = new MimeMessage
- {
- Body = new TextPart("plain") { Text = "This is just a test! Success!" },
- Subject = "Plex Requests: Test Message!",
- };
- message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
- message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
-
- await Send(message, settings);
- }
- }
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: EmailMessageNotification.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using System;
+using System.Threading.Tasks;
+
+using MailKit.Security;
+
+using MimeKit;
+using NLog;
+
+using PlexRequests.Core;
+using PlexRequests.Core.SettingModels;
+using PlexRequests.Services.Interfaces;
+using SmtpClient = MailKit.Net.Smtp.SmtpClient;
+using PlexRequests.Store;
+
+namespace PlexRequests.Services.Notification
+{
+ public class EmailMessageNotification : INotification
+ {
+ public EmailMessageNotification(ISettingsService settings)
+ {
+ EmailNotificationSettings = settings;
+ }
+
+ private static readonly Logger Log = LogManager.GetCurrentClassLogger();
+ private ISettingsService EmailNotificationSettings { get; }
+ public string NotificationName => "EmailMessageNotification";
+
+ public async Task NotifyAsync(NotificationModel model)
+ {
+ var configuration = GetConfiguration();
+ await NotifyAsync(model, configuration);
+ }
+
+ public async Task NotifyAsync(NotificationModel model, Settings settings)
+ {
+ if (settings == null) await NotifyAsync(model);
+
+ var emailSettings = (EmailNotificationSettings)settings;
+
+ if (!ValidateConfiguration(emailSettings))
+ {
+ return;
+ }
+
+ switch (model.NotificationType)
+ {
+ case NotificationType.NewRequest:
+ await EmailNewRequest(model, emailSettings);
+ break;
+ case NotificationType.Issue:
+ await EmailIssue(model, emailSettings);
+ break;
+ case NotificationType.RequestAvailable:
+ await EmailAvailableRequest(model, emailSettings);
+ break;
+ case NotificationType.RequestApproved:
+ throw new NotImplementedException();
+
+ case NotificationType.AdminNote:
+ throw new NotImplementedException();
+
+ case NotificationType.Test:
+ await EmailTest(model, emailSettings);
+ break;
+ }
+
+ }
+
+ private EmailNotificationSettings GetConfiguration()
+ {
+ var settings = EmailNotificationSettings.GetSettings();
+ return settings;
+ }
+
+ private bool ValidateConfiguration(EmailNotificationSettings settings)
+ {
+ if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString()))
+ {
+ return false;
+ }
+
+ if (!settings.EnableUserEmailNotifications)
+ {
+ if (!settings.Enabled)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private async Task EmailNewRequest(NotificationModel model, EmailNotificationSettings settings)
+ {
+ var message = new MimeMessage
+ {
+ Body = new TextPart("plain") { Text = $"Hello! The user '{model.User}' has requested the {RequestTypeDisplay.Get(model.RequestType)?.ToLower()} '{model.Title}'! Please log in to approve this request. Request Date: {model.DateTime.ToString("f")}" },
+ Subject = $"Plex Requests: New {RequestTypeDisplay.Get(model.RequestType)?.ToLower()} request for {model.Title}!"
+ };
+ message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
+ message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
+
+
+ await Send(message, settings);
+ }
+
+ private async Task EmailIssue(NotificationModel model, EmailNotificationSettings settings)
+ {
+ var message = new MimeMessage
+ {
+ Body = new TextPart("plain") { Text = $"Hello! The user '{model.User}' has reported a new issue {model.Body} for the title {model.Title}!" },
+ Subject = $"Plex Requests: New issue for {model.Title}!"
+ };
+ message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
+ message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
+
+
+ await Send(message, settings);
+ }
+
+ private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings)
+ {
+ if (!settings.EnableUserEmailNotifications)
+ {
+ await Task.FromResult(false);
+ }
+
+ var message = new MimeMessage
+ {
+ Body = new TextPart("plain") { Text = $"Hello! You requested {model.Title} on PlexRequests! This is now available on Plex! :)" },
+ Subject = $"Plex Requests: {model.Title} is now available!"
+ };
+ message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
+ message.To.Add(new MailboxAddress(model.UserEmail, model.UserEmail));
+
+ await Send(message, settings);
+ }
+
+ private async Task Send(MimeMessage message, EmailNotificationSettings settings)
+ {
+ try
+ {
+ using (var client = new SmtpClient())
+ {
+ client.Connect(settings.EmailHost, settings.EmailPort, SecureSocketOptions.Auto); // Let MailKit figure out the correct SecureSocketOptions.
+
+ // Note: since we don't have an OAuth2 token, disable
+ // the XOAUTH2 authentication mechanism.
+ client.AuthenticationMechanisms.Remove("XOAUTH2");
+
+ client.Authenticate(settings.EmailUsername, settings.EmailPassword);
+
+ await client.SendAsync(message);
+ await client.DisconnectAsync(true);
+ }
+ }
+ catch (Exception e)
+ {
+ Log.Error(e);
+ }
+ }
+
+ private async Task EmailTest(NotificationModel model, EmailNotificationSettings settings)
+ {
+ var message = new MimeMessage
+ {
+ Body = new TextPart("plain") { Text = "This is just a test! Success!" },
+ Subject = "Plex Requests: Test Message!",
+ };
+ message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
+ message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
+
+ await Send(message, settings);
+ }
+ }
}
\ No newline at end of file
diff --git a/PlexRequests.Services/Notification/NotificationModel.cs b/PlexRequests.Services/Notification/NotificationModel.cs
index 2cc4e7fdb..e74f90dd4 100644
--- a/PlexRequests.Services/Notification/NotificationModel.cs
+++ b/PlexRequests.Services/Notification/NotificationModel.cs
@@ -1,40 +1,42 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: NotificationModel.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using System;
-
-namespace PlexRequests.Services.Notification
-{
- public class NotificationModel
- {
- public string Title { get; set; }
- public string Body { get; set; }
- public DateTime DateTime { get; set; }
- public NotificationType NotificationType { get; set; }
- public string User { get; set; }
- public string UserEmail { get; set; }
- }
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: NotificationModel.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using PlexRequests.Store;
+using System;
+
+namespace PlexRequests.Services.Notification
+{
+ public class NotificationModel
+ {
+ public string Title { get; set; }
+ public string Body { get; set; }
+ public DateTime DateTime { get; set; }
+ public NotificationType NotificationType { get; set; }
+ public string User { get; set; }
+ public string UserEmail { get; set; }
+ public RequestType RequestType { get; set; }
+ }
}
\ No newline at end of file
diff --git a/PlexRequests.Services/Notification/PushbulletNotification.cs b/PlexRequests.Services/Notification/PushbulletNotification.cs
index 70f318331..8eda8d0b9 100644
--- a/PlexRequests.Services/Notification/PushbulletNotification.cs
+++ b/PlexRequests.Services/Notification/PushbulletNotification.cs
@@ -1,142 +1,143 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: PushbulletNotification.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using System;
-using System.Threading.Tasks;
-
-using NLog;
-
-using PlexRequests.Api.Interfaces;
-using PlexRequests.Core;
-using PlexRequests.Core.SettingModels;
-using PlexRequests.Services.Interfaces;
-
-namespace PlexRequests.Services.Notification
-{
- public class PushbulletNotification : INotification
- {
- public PushbulletNotification(IPushbulletApi pushbulletApi, ISettingsService settings)
- {
- PushbulletApi = pushbulletApi;
- SettingsService = settings;
- }
- private IPushbulletApi PushbulletApi { get; }
- private ISettingsService SettingsService { get; }
-
- private static Logger Log = LogManager.GetCurrentClassLogger();
- public string NotificationName => "PushbulletNotification";
- public async Task NotifyAsync(NotificationModel model)
- {
- var configuration = GetSettings();
- await NotifyAsync(model, configuration);
- }
-
- public async Task NotifyAsync(NotificationModel model, Settings settings)
- {
- if (settings == null) await NotifyAsync(model);
-
- var pushSettings = (PushbulletNotificationSettings)settings;
-
- if (!ValidateConfiguration(pushSettings)) return;
-
- switch (model.NotificationType)
- {
- case NotificationType.NewRequest:
- await PushNewRequestAsync(model, pushSettings);
- break;
- case NotificationType.Issue:
- await PushIssueAsync(model, pushSettings);
- break;
- case NotificationType.RequestAvailable:
- break;
- case NotificationType.RequestApproved:
- break;
- case NotificationType.AdminNote:
- break;
- case NotificationType.Test:
- await PushTestAsync(pushSettings);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
-
- private bool ValidateConfiguration(PushbulletNotificationSettings settings)
- {
- if (!settings.Enabled)
- {
- return false;
- }
- if (string.IsNullOrEmpty(settings.AccessToken))
- {
- return false;
- }
- return true;
- }
-
- private PushbulletNotificationSettings GetSettings()
- {
- return SettingsService.GetSettings();
- }
-
- private async Task PushNewRequestAsync(NotificationModel model, PushbulletNotificationSettings settings)
- {
- var message = $"{model.Title} has been requested by user: {model.User}";
- var pushTitle = $"Plex Requests: {model.Title} has been requested!";
- await Push(settings, message, pushTitle);
- }
-
- private async Task PushIssueAsync(NotificationModel model, PushbulletNotificationSettings settings)
- {
- var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
- var pushTitle = $"Plex Requests: A new issue has been reported for {model.Title}";
- await Push(settings, message, pushTitle);
- }
-
- private async Task PushTestAsync(PushbulletNotificationSettings settings)
- {
- var message = "This is just a test! Success!";
- var pushTitle = "Plex Requests: Test Message!";
- await Push(settings, message, pushTitle);
- }
-
- private async Task Push(PushbulletNotificationSettings settings, string message, string title)
- {
- try
- {
- var result = await PushbulletApi.PushAsync(settings.AccessToken, title, message, settings.DeviceIdentifier);
- if (result != null)
- {
- Log.Error("Pushbullet api returned a null value, the notification did not get pushed");
- }
- }
- catch (Exception e)
- {
- Log.Error(e);
- }
- }
- }
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: PushbulletNotification.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using System;
+using System.Threading.Tasks;
+
+using NLog;
+
+using PlexRequests.Api.Interfaces;
+using PlexRequests.Core;
+using PlexRequests.Core.SettingModels;
+using PlexRequests.Services.Interfaces;
+using PlexRequests.Store;
+
+namespace PlexRequests.Services.Notification
+{
+ public class PushbulletNotification : INotification
+ {
+ public PushbulletNotification(IPushbulletApi pushbulletApi, ISettingsService settings)
+ {
+ PushbulletApi = pushbulletApi;
+ SettingsService = settings;
+ }
+ private IPushbulletApi PushbulletApi { get; }
+ private ISettingsService SettingsService { get; }
+
+ private static Logger Log = LogManager.GetCurrentClassLogger();
+ public string NotificationName => "PushbulletNotification";
+ public async Task NotifyAsync(NotificationModel model)
+ {
+ var configuration = GetSettings();
+ await NotifyAsync(model, configuration);
+ }
+
+ public async Task NotifyAsync(NotificationModel model, Settings settings)
+ {
+ if (settings == null) await NotifyAsync(model);
+
+ var pushSettings = (PushbulletNotificationSettings)settings;
+
+ if (!ValidateConfiguration(pushSettings)) return;
+
+ switch (model.NotificationType)
+ {
+ case NotificationType.NewRequest:
+ await PushNewRequestAsync(model, pushSettings);
+ break;
+ case NotificationType.Issue:
+ await PushIssueAsync(model, pushSettings);
+ break;
+ case NotificationType.RequestAvailable:
+ break;
+ case NotificationType.RequestApproved:
+ break;
+ case NotificationType.AdminNote:
+ break;
+ case NotificationType.Test:
+ await PushTestAsync(pushSettings);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private bool ValidateConfiguration(PushbulletNotificationSettings settings)
+ {
+ if (!settings.Enabled)
+ {
+ return false;
+ }
+ if (string.IsNullOrEmpty(settings.AccessToken))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private PushbulletNotificationSettings GetSettings()
+ {
+ return SettingsService.GetSettings();
+ }
+
+ private async Task PushNewRequestAsync(NotificationModel model, PushbulletNotificationSettings settings)
+ {
+ var message = $"The {RequestTypeDisplay.Get(model.RequestType)?.ToLower()} '{model.Title}' has been requested by user: {model.User}";
+ var pushTitle = $"Plex Requests: The {RequestTypeDisplay.Get(model.RequestType)?.ToLower()} {model.Title} has been requested!";
+ await Push(settings, message, pushTitle);
+ }
+
+ private async Task PushIssueAsync(NotificationModel model, PushbulletNotificationSettings settings)
+ {
+ var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
+ var pushTitle = $"Plex Requests: A new issue has been reported for {model.Title}";
+ await Push(settings, message, pushTitle);
+ }
+
+ private async Task PushTestAsync(PushbulletNotificationSettings settings)
+ {
+ var message = "This is just a test! Success!";
+ var pushTitle = "Plex Requests: Test Message!";
+ await Push(settings, message, pushTitle);
+ }
+
+ private async Task Push(PushbulletNotificationSettings settings, string message, string title)
+ {
+ try
+ {
+ var result = await PushbulletApi.PushAsync(settings.AccessToken, title, message, settings.DeviceIdentifier);
+ if (result != null)
+ {
+ Log.Error("Pushbullet api returned a null value, the notification did not get pushed");
+ }
+ }
+ catch (Exception e)
+ {
+ Log.Error(e);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/PlexRequests.Services/Notification/PushoverNotification.cs b/PlexRequests.Services/Notification/PushoverNotification.cs
index d39492563..9831e6562 100644
--- a/PlexRequests.Services/Notification/PushoverNotification.cs
+++ b/PlexRequests.Services/Notification/PushoverNotification.cs
@@ -1,139 +1,140 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: PushbulletNotification.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using System;
-using System.Threading.Tasks;
-
-using NLog;
-
-using PlexRequests.Api.Interfaces;
-using PlexRequests.Core;
-using PlexRequests.Core.SettingModels;
-using PlexRequests.Services.Interfaces;
-
-namespace PlexRequests.Services.Notification
-{
- public class PushoverNotification : INotification
- {
- public PushoverNotification(IPushoverApi pushoverApi, ISettingsService settings)
- {
- PushoverApi = pushoverApi;
- SettingsService = settings;
- }
- private IPushoverApi PushoverApi { get; }
- private ISettingsService SettingsService { get; }
-
- private static Logger Log = LogManager.GetCurrentClassLogger();
- public string NotificationName => "PushoverNotification";
- public async Task NotifyAsync(NotificationModel model)
- {
- var configuration = GetSettings();
- await NotifyAsync(model, configuration);
- }
-
- public async Task NotifyAsync(NotificationModel model, Settings settings)
- {
- if (settings == null) await NotifyAsync(model);
-
- var pushSettings = (PushoverNotificationSettings)settings;
-
- if (!ValidateConfiguration(pushSettings)) return;
-
- switch (model.NotificationType)
- {
- case NotificationType.NewRequest:
- await PushNewRequestAsync(model, pushSettings);
- break;
- case NotificationType.Issue:
- await PushIssueAsync(model, pushSettings);
- break;
- case NotificationType.RequestAvailable:
- break;
- case NotificationType.RequestApproved:
- break;
- case NotificationType.AdminNote:
- break;
- case NotificationType.Test:
- await PushTestAsync(model, pushSettings);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
-
- private bool ValidateConfiguration(PushoverNotificationSettings settings)
- {
- if (!settings.Enabled)
- {
- return false;
- }
- if (string.IsNullOrEmpty(settings.AccessToken) || string.IsNullOrEmpty(settings.UserToken))
- {
- return false;
- }
- return true;
- }
-
- private PushoverNotificationSettings GetSettings()
- {
- return SettingsService.GetSettings();
- }
-
- private async Task PushNewRequestAsync(NotificationModel model, PushoverNotificationSettings settings)
- {
- var message = $"Plex Requests: {model.Title} has been requested by user: {model.User}";
- await Push(settings, message);
- }
-
- private async Task PushIssueAsync(NotificationModel model, PushoverNotificationSettings settings)
- {
- var message = $"Plex Requests: A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
- await Push(settings, message);
- }
-
- private async Task PushTestAsync(NotificationModel model, PushoverNotificationSettings settings)
- {
- var message = $"Plex Requests: Test Message!";
- await Push(settings, message);
- }
-
- private async Task Push(PushoverNotificationSettings settings, string message)
- {
- try
- {
- var result = await PushoverApi.PushAsync(settings.AccessToken, message, settings.UserToken);
- if (result?.status != 1)
- {
- Log.Error("Pushover api returned a status that was not 1, the notification did not get pushed");
- }
- }
- catch (Exception e)
- {
- Log.Error(e);
- }
- }
- }
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: PushbulletNotification.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using System;
+using System.Threading.Tasks;
+
+using NLog;
+
+using PlexRequests.Api.Interfaces;
+using PlexRequests.Core;
+using PlexRequests.Core.SettingModels;
+using PlexRequests.Services.Interfaces;
+using PlexRequests.Store;
+
+namespace PlexRequests.Services.Notification
+{
+ public class PushoverNotification : INotification
+ {
+ public PushoverNotification(IPushoverApi pushoverApi, ISettingsService settings)
+ {
+ PushoverApi = pushoverApi;
+ SettingsService = settings;
+ }
+ private IPushoverApi PushoverApi { get; }
+ private ISettingsService SettingsService { get; }
+
+ private static Logger Log = LogManager.GetCurrentClassLogger();
+ public string NotificationName => "PushoverNotification";
+ public async Task NotifyAsync(NotificationModel model)
+ {
+ var configuration = GetSettings();
+ await NotifyAsync(model, configuration);
+ }
+
+ public async Task NotifyAsync(NotificationModel model, Settings settings)
+ {
+ if (settings == null) await NotifyAsync(model);
+
+ var pushSettings = (PushoverNotificationSettings)settings;
+
+ if (!ValidateConfiguration(pushSettings)) return;
+
+ switch (model.NotificationType)
+ {
+ case NotificationType.NewRequest:
+ await PushNewRequestAsync(model, pushSettings);
+ break;
+ case NotificationType.Issue:
+ await PushIssueAsync(model, pushSettings);
+ break;
+ case NotificationType.RequestAvailable:
+ break;
+ case NotificationType.RequestApproved:
+ break;
+ case NotificationType.AdminNote:
+ break;
+ case NotificationType.Test:
+ await PushTestAsync(model, pushSettings);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private bool ValidateConfiguration(PushoverNotificationSettings settings)
+ {
+ if (!settings.Enabled)
+ {
+ return false;
+ }
+ if (string.IsNullOrEmpty(settings.AccessToken) || string.IsNullOrEmpty(settings.UserToken))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private PushoverNotificationSettings GetSettings()
+ {
+ return SettingsService.GetSettings();
+ }
+
+ private async Task PushNewRequestAsync(NotificationModel model, PushoverNotificationSettings settings)
+ {
+ var message = $"Plex Requests: The {RequestTypeDisplay.Get(model.RequestType)?.ToLower()} '{model.Title}' has been requested by user: {model.User}";
+ await Push(settings, message);
+ }
+
+ private async Task PushIssueAsync(NotificationModel model, PushoverNotificationSettings settings)
+ {
+ var message = $"Plex Requests: A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
+ await Push(settings, message);
+ }
+
+ private async Task PushTestAsync(NotificationModel model, PushoverNotificationSettings settings)
+ {
+ var message = $"Plex Requests: Test Message!";
+ await Push(settings, message);
+ }
+
+ private async Task Push(PushoverNotificationSettings settings, string message)
+ {
+ try
+ {
+ var result = await PushoverApi.PushAsync(settings.AccessToken, message, settings.UserToken);
+ if (result?.status != 1)
+ {
+ Log.Error("Pushover api returned a status that was not 1, the notification did not get pushed");
+ }
+ }
+ catch (Exception e)
+ {
+ Log.Error(e);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/PlexRequests.Store/RequestedModel.cs b/PlexRequests.Store/RequestedModel.cs
index c63ede547..254b4f7be 100644
--- a/PlexRequests.Store/RequestedModel.cs
+++ b/PlexRequests.Store/RequestedModel.cs
@@ -1,90 +1,108 @@
-using System;
-using Dapper.Contrib.Extensions;
-using System.Collections.Generic;
-using System.Linq;
-using Newtonsoft.Json;
-
-namespace PlexRequests.Store
-{
- [Table("Requested")]
- public class RequestedModel : Entity
- {
- public RequestedModel()
- {
- RequestedUsers = new List();
- }
-
- // ReSharper disable once IdentifierTypo
- public int ProviderId { get; set; }
- public string ImdbId { get; set; }
- public string TvDbId { get; set; }
- public string Overview { get; set; }
- public string Title { get; set; }
- public string PosterPath { get; set; }
- public DateTime ReleaseDate { get; set; }
- public RequestType Type { get; set; }
- public string Status { get; set; }
- public bool Approved { get; set; }
-
- [Obsolete("Use RequestedUsers")]
- public string RequestedBy { get; set; }
-
- public DateTime RequestedDate { get; set; }
- public bool Available { get; set; }
- public IssueState Issues { get; set; }
- public string OtherMessage { get; set; }
- public string AdminNote { get; set; }
- public int[] SeasonList { get; set; }
- public int SeasonCount { get; set; }
- public string SeasonsRequested { get; set; }
- public string MusicBrainzId { get; set; }
- public List RequestedUsers { get; set; }
- public string ArtistName { get; set; }
- public string ArtistId { get; set; }
- public int IssueId { get; set; }
-
- [JsonIgnore]
- public List AllUsers
- {
- get
- {
- var u = new List();
- if (!string.IsNullOrEmpty(RequestedBy))
- {
- u.Add(RequestedBy);
- }
-
- if (RequestedUsers.Any())
- {
- u.AddRange(RequestedUsers.Where(requestedUser => requestedUser != RequestedBy));
- }
- return u;
- }
- }
-
- [JsonIgnore]
- public bool CanApprove => !Approved && !Available;
-
- public bool UserHasRequested(string username)
- {
- return AllUsers.Any(x => x.Equals(username, StringComparison.OrdinalIgnoreCase));
- }
- }
-
- public enum RequestType
- {
- Movie,
- TvShow,
- Album
- }
-
- public enum IssueState
- {
- None = 99,
- WrongAudio = 0,
- NoSubtitles = 1,
- WrongContent = 2,
- PlaybackIssues = 3,
- Other = 4, // Provide a message
- }
-}
+using System;
+using Dapper.Contrib.Extensions;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+
+namespace PlexRequests.Store
+{
+ [Table("Requested")]
+ public class RequestedModel : Entity
+ {
+ public RequestedModel()
+ {
+ RequestedUsers = new List();
+ }
+
+ // ReSharper disable once IdentifierTypo
+ public int ProviderId { get; set; }
+ public string ImdbId { get; set; }
+ public string TvDbId { get; set; }
+ public string Overview { get; set; }
+ public string Title { get; set; }
+ public string PosterPath { get; set; }
+ public DateTime ReleaseDate { get; set; }
+ public RequestType Type { get; set; }
+ public string Status { get; set; }
+ public bool Approved { get; set; }
+
+ [Obsolete("Use RequestedUsers")]
+ public string RequestedBy { get; set; }
+
+ public DateTime RequestedDate { get; set; }
+ public bool Available { get; set; }
+ public IssueState Issues { get; set; }
+ public string OtherMessage { get; set; }
+ public string AdminNote { get; set; }
+ public int[] SeasonList { get; set; }
+ public int SeasonCount { get; set; }
+ public string SeasonsRequested { get; set; }
+ public string MusicBrainzId { get; set; }
+ public List RequestedUsers { get; set; }
+ public string ArtistName { get; set; }
+ public string ArtistId { get; set; }
+ public int IssueId { get; set; }
+
+ [JsonIgnore]
+ public List AllUsers
+ {
+ get
+ {
+ var u = new List();
+ if (!string.IsNullOrEmpty(RequestedBy))
+ {
+ u.Add(RequestedBy);
+ }
+
+ if (RequestedUsers.Any())
+ {
+ u.AddRange(RequestedUsers.Where(requestedUser => requestedUser != RequestedBy));
+ }
+ return u;
+ }
+ }
+
+ [JsonIgnore]
+ public bool CanApprove => !Approved && !Available;
+
+ public bool UserHasRequested(string username)
+ {
+ return AllUsers.Any(x => x.Equals(username, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+
+ public enum RequestType
+ {
+ Movie,
+ TvShow,
+ Album
+ }
+
+ public static class RequestTypeDisplay
+ {
+ public static string Get(RequestType type)
+ {
+ switch (type)
+ {
+ case RequestType.Movie:
+ return "Movie";
+ case RequestType.TvShow:
+ return "TV Show";
+ case RequestType.Album:
+ return "Album";
+ default:
+ return string.Empty;
+ }
+ }
+ }
+
+ public enum IssueState
+ {
+ None = 99,
+ WrongAudio = 0,
+ NoSubtitles = 1,
+ WrongContent = 2,
+ PlaybackIssues = 3,
+ Other = 4, // Provide a message
+ }
+}
diff --git a/PlexRequests.UI.Tests/AdminModuleTests.cs b/PlexRequests.UI.Tests/AdminModuleTests.cs
index 66245d649..198be036f 100644
--- a/PlexRequests.UI.Tests/AdminModuleTests.cs
+++ b/PlexRequests.UI.Tests/AdminModuleTests.cs
@@ -1,361 +1,365 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: UserLoginModuleTests.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using System.Collections.Generic;
-using System.Linq;
-
-using Moq;
-
-using Nancy;
-using Nancy.Testing;
-
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-using NUnit.Framework;
-
-using PlexRequests.Api.Interfaces;
-using PlexRequests.Api.Models.Plex;
-using PlexRequests.Core;
-using PlexRequests.Core.SettingModels;
-using PlexRequests.Services.Interfaces;
-using PlexRequests.Store.Models;
-using PlexRequests.Store.Repository;
-using PlexRequests.UI.Models;
-using PlexRequests.UI.Modules;
-using PlexRequests.Helpers;
-using PlexRequests.UI.Helpers;
-
-namespace PlexRequests.UI.Tests
-{
- [TestFixture]
- public class AdminModuleTests
- {
- private Mock> PlexRequestMock { get; set; }
- private Mock> CpMock { get; set; }
- private Mock> AuthMock { get; set; }
- private Mock> PlexSettingsMock { get; set; }
- private Mock> SonarrSettingsMock { get; set; }
- private Mock> SickRageSettingsMock { get; set; }
- private Mock> ScheduledJobsSettingsMock { get; set; }
- private Mock> EmailMock { get; set; }
- private Mock> PushbulletSettings { get; set; }
- private Mock> PushoverSettings { get; set; }
- private Mock> HeadphonesSettings { get; set; }
- private Mock PlexMock { get; set; }
- private Mock SonarrApiMock { get; set; }
- private Mock PushbulletApi { get; set; }
- private Mock PushoverApi { get; set; }
- private Mock CpApi { get; set; }
- private Mock RecorderMock { get; set; }
- private Mock> LogRepo { get; set; }
- private Mock NotificationService { get; set; }
- private Mock Cache { get; set; }
- private Mock> Log { get; set; }
- private Mock> SlackSettings { get; set; }
- private Mock> LandingPageSettings { get; set; }
- private Mock SlackApi { get; set; }
-
- private ConfigurableBootstrapper Bootstrapper { get; set; }
-
- [SetUp]
- public void Setup()
- {
- AuthMock = new Mock>();
- var expectedSettings = new AuthenticationSettings { UserAuthentication = false, PlexAuthToken = "abc" };
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
-
- PlexMock = new Mock();
- PlexMock.Setup(x => x.SignIn("Username1", "Password1"))
- .Returns(new PlexAuthentication { user = new User { authentication_token = "abc", title = "Username1" } });
-
- PlexRequestMock = new Mock>();
- PlexRequestMock.Setup(x => x.GetSettings()).Returns(new PlexRequestSettings());
- CpMock = new Mock>();
- PlexSettingsMock = new Mock>();
- SonarrApiMock = new Mock();
- SonarrSettingsMock = new Mock>();
- EmailMock = new Mock>();
- PushbulletApi = new Mock();
- PushbulletSettings = new Mock>();
- CpApi = new Mock();
- SickRageSettingsMock = new Mock>();
- LogRepo = new Mock>();
- PushoverSettings = new Mock>();
- PushoverApi = new Mock();
- NotificationService = new Mock();
- HeadphonesSettings = new Mock>();
- Cache = new Mock();
- Log = new Mock>();
- SlackApi = new Mock();
- SlackSettings = new Mock>();
- LandingPageSettings = new Mock>();
- ScheduledJobsSettingsMock = new Mock>();
- RecorderMock = new Mock();
-
-
- Bootstrapper = new ConfigurableBootstrapper(with =>
- {
- with.Module();
- with.Dependency(AuthMock.Object);
- with.Dependency(PlexRequestMock.Object);
- with.Dependency(CpMock.Object);
- with.Dependency(PlexSettingsMock.Object);
- with.Dependency(SonarrApiMock.Object);
- with.Dependency(SonarrSettingsMock.Object);
- with.Dependency(PlexMock.Object);
- with.Dependency(EmailMock.Object);
- with.Dependency(PushbulletApi.Object);
- with.Dependency(PushbulletSettings.Object);
- with.Dependency(CpApi.Object);
- with.Dependency(SickRageSettingsMock.Object);
- with.Dependency(LogRepo.Object);
- with.Dependency(PushoverSettings.Object);
- with.Dependency(PushoverApi.Object);
- with.Dependency(NotificationService.Object);
- with.Dependency(HeadphonesSettings.Object);
- with.Dependency(Cache.Object);
- with.Dependency(Log.Object);
- with.Dependency(SlackApi.Object);
- with.Dependency(LandingPageSettings.Object);
- with.Dependency(SlackSettings.Object);
- with.Dependency(ScheduledJobsSettingsMock.Object);
- with.Dependency(RecorderMock.Object);
- with.RootPathProvider();
- with.RequestStartup((container, pipelines, context) =>
- {
- context.CurrentUser = new UserIdentity { UserName = "user", Claims = new List {"Admin"} };
- });
- });
-
- Bootstrapper.WithSession(new Dictionary());
- }
-
- [Test]
- public void RequestAuthTokenTestNewSettings()
- {
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Post("/admin/requestauth", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Username1");
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
- PlexMock.Verify(x => x.SignIn("Username1", "Password1"), Times.Once);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Once);
- }
-
- [Test]
- public void RequestAuthTokenTestEmptyCredentials()
- {
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Post("/admin/requestauth", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", string.Empty);
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(false));
- Assert.That(body.Message, Is.Not.Empty);
-
- PlexMock.Verify(x => x.SignIn("Username1", "Password1"), Times.Never);
- AuthMock.Verify(x => x.GetSettings(), Times.Never);
- AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Never);
- }
-
- [Test]
- public void RequestAuthTokenTesPlexSignInFail()
- {
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Post("/admin/requestauth", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Badusername");
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(false));
- Assert.That(body.Message, Is.Not.Empty);
-
- PlexMock.Verify(x => x.SignIn("Badusername", "Password1"), Times.Once);
- AuthMock.Verify(x => x.GetSettings(), Times.Never);
- AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Never);
- }
-
- [Test]
- public void RequestAuthTokenTestExistingSettings()
- {
- AuthMock.Setup(x => x.GetSettings()).Returns(() => null);
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Post("/admin/requestauth", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Username1");
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
-
- PlexMock.Verify(x => x.SignIn("Username1", "Password1"), Times.Once);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Once);
- }
-
- [Test]
- public void GetUsersSuccessfully()
- {
- var users = new PlexFriends { User = new[] { new UserFriends { Title = "abc2" }, } };
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(users);
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Get("/admin/getusers", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Username1");
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- var user = body["users"];
- Assert.That(body, Is.Not.Null);
- Assert.That(user.ToString().Contains("abc"), Is.True);
-
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- }
-
- [Test]
- public void GetUsersReturnsNoUsers()
- {
- var users = new PlexFriends();
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(users);
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Get("/admin/getusers", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Username1");
- with.FormValue("password", "Password1");
-
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body, Is.Not.Null);
- Assert.That(string.IsNullOrWhiteSpace(body), Is.True);
-
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- }
-
- [Test]
- public void GetUsersReturnsNull()
- {
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(() => null);
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Get("/admin/getusers", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Username1");
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body, Is.Not.Null);
- Assert.That(string.IsNullOrWhiteSpace(body), Is.True);
-
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- }
-
- [Test]
- public void GetUsersTokenIsNull()
- {
- AuthMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings());
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Get("/admin/getusers", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("username", "Username1");
- with.FormValue("password", "Password1");
-
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- var user = (string)body["users"];
- Assert.That(body, Is.Not.Null);
- Assert.That(string.IsNullOrWhiteSpace(user), Is.True);
-
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Never);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- }
- }
+#region Copyright
+// /************************************************************************
+// Copyright (c) 2016 Jamie Rees
+// File: UserLoginModuleTests.cs
+// Created By: Jamie Rees
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ************************************************************************/
+#endregion
+using System.Collections.Generic;
+using System.Linq;
+
+using Moq;
+
+using Nancy;
+using Nancy.Testing;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+using NUnit.Framework;
+
+using PlexRequests.Api.Interfaces;
+using PlexRequests.Api.Models.Plex;
+using PlexRequests.Core;
+using PlexRequests.Core.SettingModels;
+using PlexRequests.Services.Interfaces;
+using PlexRequests.Store.Models;
+using PlexRequests.Store.Repository;
+using PlexRequests.UI.Models;
+using PlexRequests.UI.Modules;
+using PlexRequests.Helpers;
+using PlexRequests.Helpers.Analytics;
+using PlexRequests.UI.Helpers;
+
+namespace PlexRequests.UI.Tests
+{
+ [TestFixture]
+ public class AdminModuleTests
+ {
+ private Mock> PlexRequestMock { get; set; }
+ private Mock> CpMock { get; set; }
+ private Mock> AuthMock { get; set; }
+ private Mock> PlexSettingsMock { get; set; }
+ private Mock> SonarrSettingsMock { get; set; }
+ private Mock> SickRageSettingsMock { get; set; }
+ private Mock> ScheduledJobsSettingsMock { get; set; }
+ private Mock> EmailMock { get; set; }
+ private Mock> PushbulletSettings { get; set; }
+ private Mock> PushoverSettings { get; set; }
+ private Mock> HeadphonesSettings { get; set; }
+ private Mock PlexMock { get; set; }
+ private Mock SonarrApiMock { get; set; }
+ private Mock PushbulletApi { get; set; }
+ private Mock PushoverApi { get; set; }
+ private Mock CpApi { get; set; }
+ private Mock RecorderMock { get; set; }
+ private Mock> LogRepo { get; set; }
+ private Mock NotificationService { get; set; }
+ private Mock Cache { get; set; }
+ private Mock> Log { get; set; }
+ private Mock> SlackSettings { get; set; }
+ private Mock> LandingPageSettings { get; set; }
+ private Mock SlackApi { get; set; }
+ private Mock IAnalytics { get; set; }
+
+ private ConfigurableBootstrapper Bootstrapper { get; set; }
+
+ [SetUp]
+ public void Setup()
+ {
+ AuthMock = new Mock>();
+ var expectedSettings = new AuthenticationSettings { UserAuthentication = false, PlexAuthToken = "abc" };
+ AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
+
+ PlexMock = new Mock();
+ PlexMock.Setup(x => x.SignIn("Username1", "Password1"))
+ .Returns(new PlexAuthentication { user = new User { authentication_token = "abc", title = "Username1" } });
+
+ PlexRequestMock = new Mock>();
+ PlexRequestMock.Setup(x => x.GetSettings()).Returns(new PlexRequestSettings());
+ CpMock = new Mock>();
+ PlexSettingsMock = new Mock>();
+ SonarrApiMock = new Mock();
+ SonarrSettingsMock = new Mock>();
+ EmailMock = new Mock>();
+ PushbulletApi = new Mock();
+ PushbulletSettings = new Mock>();
+ CpApi = new Mock();
+ SickRageSettingsMock = new Mock>();
+ LogRepo = new Mock>();
+ PushoverSettings = new Mock>();
+ PushoverApi = new Mock();
+ NotificationService = new Mock();
+ HeadphonesSettings = new Mock>();
+ Cache = new Mock();
+ Log = new Mock>();
+ SlackApi = new Mock();
+ SlackSettings = new Mock>();
+ LandingPageSettings = new Mock>();
+ ScheduledJobsSettingsMock = new Mock>();
+ RecorderMock = new Mock();
+ IAnalytics = new Mock();
+
+
+ Bootstrapper = new ConfigurableBootstrapper(with =>
+ {
+ with.Module();
+ with.Dependency(AuthMock.Object);
+ with.Dependency(PlexRequestMock.Object);
+ with.Dependency(CpMock.Object);
+ with.Dependency(PlexSettingsMock.Object);
+ with.Dependency(SonarrApiMock.Object);
+ with.Dependency(SonarrSettingsMock.Object);
+ with.Dependency(PlexMock.Object);
+ with.Dependency(EmailMock.Object);
+ with.Dependency(PushbulletApi.Object);
+ with.Dependency(PushbulletSettings.Object);
+ with.Dependency(CpApi.Object);
+ with.Dependency(SickRageSettingsMock.Object);
+ with.Dependency(LogRepo.Object);
+ with.Dependency(PushoverSettings.Object);
+ with.Dependency(PushoverApi.Object);
+ with.Dependency(NotificationService.Object);
+ with.Dependency(IAnalytics.Object);
+ with.Dependency(HeadphonesSettings.Object);
+ with.Dependency(Cache.Object);
+ with.Dependency(Log.Object);
+ with.Dependency(SlackApi.Object);
+ with.Dependency(LandingPageSettings.Object);
+ with.Dependency(SlackSettings.Object);
+ with.Dependency(ScheduledJobsSettingsMock.Object);
+ with.Dependency(RecorderMock.Object);
+ with.RootPathProvider();
+ with.RequestStartup((container, pipelines, context) =>
+ {
+ context.CurrentUser = new UserIdentity { UserName = "user", Claims = new List {"Admin"} };
+ });
+ });
+
+ Bootstrapper.WithSession(new Dictionary());
+ }
+
+ [Test]
+ public void RequestAuthTokenTestNewSettings()
+ {
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Post("/admin/requestauth", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Username1");
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ Assert.That(body.Result, Is.EqualTo(true));
+ PlexMock.Verify(x => x.SignIn("Username1", "Password1"), Times.Once);
+ AuthMock.Verify(x => x.GetSettings(), Times.Once);
+ AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Once);
+ }
+
+ [Test]
+ public void RequestAuthTokenTestEmptyCredentials()
+ {
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Post("/admin/requestauth", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", string.Empty);
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ Assert.That(body.Result, Is.EqualTo(false));
+ Assert.That(body.Message, Is.Not.Empty);
+
+ PlexMock.Verify(x => x.SignIn("Username1", "Password1"), Times.Never);
+ AuthMock.Verify(x => x.GetSettings(), Times.Never);
+ AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Never);
+ }
+
+ [Test]
+ public void RequestAuthTokenTesPlexSignInFail()
+ {
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Post("/admin/requestauth", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Badusername");
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ Assert.That(body.Result, Is.EqualTo(false));
+ Assert.That(body.Message, Is.Not.Empty);
+
+ PlexMock.Verify(x => x.SignIn("Badusername", "Password1"), Times.Once);
+ AuthMock.Verify(x => x.GetSettings(), Times.Never);
+ AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Never);
+ }
+
+ [Test]
+ public void RequestAuthTokenTestExistingSettings()
+ {
+ AuthMock.Setup(x => x.GetSettings()).Returns(() => null);
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Post("/admin/requestauth", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Username1");
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ Assert.That(body.Result, Is.EqualTo(true));
+
+ PlexMock.Verify(x => x.SignIn("Username1", "Password1"), Times.Once);
+ AuthMock.Verify(x => x.GetSettings(), Times.Once);
+ AuthMock.Verify(x => x.SaveSettings(It.IsAny()), Times.Once);
+ }
+
+ [Test]
+ public void GetUsersSuccessfully()
+ {
+ var users = new PlexFriends { User = new[] { new UserFriends { Title = "abc2" }, } };
+ PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(users);
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Get("/admin/getusers", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Username1");
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ var user = body["users"];
+ Assert.That(body, Is.Not.Null);
+ Assert.That(user.ToString().Contains("abc"), Is.True);
+
+ PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
+ AuthMock.Verify(x => x.GetSettings(), Times.Once);
+ }
+
+ [Test]
+ public void GetUsersReturnsNoUsers()
+ {
+ var users = new PlexFriends();
+ PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(users);
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Get("/admin/getusers", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Username1");
+ with.FormValue("password", "Password1");
+
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ Assert.That(body, Is.Not.Null);
+ Assert.That(string.IsNullOrWhiteSpace(body), Is.True);
+
+ PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
+ AuthMock.Verify(x => x.GetSettings(), Times.Once);
+ }
+
+ [Test]
+ public void GetUsersReturnsNull()
+ {
+ PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(() => null);
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Get("/admin/getusers", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Username1");
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ Assert.That(body, Is.Not.Null);
+ Assert.That(string.IsNullOrWhiteSpace(body), Is.True);
+
+ PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
+ AuthMock.Verify(x => x.GetSettings(), Times.Once);
+ }
+
+ [Test]
+ public void GetUsersTokenIsNull()
+ {
+ AuthMock.Setup(x => x.GetSettings()).Returns(new AuthenticationSettings());
+ var browser = new Browser(Bootstrapper);
+
+ var result = browser.Get("/admin/getusers", with =>
+ {
+ with.HttpRequest();
+ with.Header("Accept", "application/json");
+ with.FormValue("username", "Username1");
+ with.FormValue("password", "Password1");
+
+ });
+
+ Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
+
+ var body = JsonConvert.DeserializeObject(result.Body.AsString());
+ var user = (string)body["users"];
+ Assert.That(body, Is.Not.Null);
+ Assert.That(string.IsNullOrWhiteSpace(user), Is.True);
+
+ PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Never);
+ AuthMock.Verify(x => x.GetSettings(), Times.Once);
+ }
+ }
}
\ No newline at end of file
diff --git a/PlexRequests.UI.Tests/UserLoginModuleTests.cs b/PlexRequests.UI.Tests/UserLoginModuleTests.cs
index 22d000575..c962fa335 100644
--- a/PlexRequests.UI.Tests/UserLoginModuleTests.cs
+++ b/PlexRequests.UI.Tests/UserLoginModuleTests.cs
@@ -1,437 +1,441 @@
-#region Copyright
-// /************************************************************************
-// Copyright (c) 2016 Jamie Rees
-// File: UserLoginModuleTests.cs
-// Created By: Jamie Rees
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ************************************************************************/
-#endregion
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-using Moq;
-
-using Nancy;
-using Nancy.Testing;
-
-using Newtonsoft.Json;
-
-using NUnit.Framework;
-
-using PlexRequests.Api.Interfaces;
-using PlexRequests.Api.Models.Plex;
-using PlexRequests.Core;
-using PlexRequests.Core.SettingModels;
-using PlexRequests.UI.Models;
-using PlexRequests.UI.Modules;
-
-namespace PlexRequests.UI.Tests
-{
- [TestFixture]
- public class UserLoginModuleTests
- {
- private Mock> AuthMock { get; set; }
- private Mock> PlexRequestMock { get; set; }
- private Mock> LandingPageMock { get; set; }
- private ConfigurableBootstrapper Bootstrapper { get; set; }
- private Mock PlexMock { get; set; }
-
- [SetUp]
- public void Setup()
- {
- AuthMock = new Mock>();
- PlexMock = new Mock();
- LandingPageMock = new Mock>();
- PlexRequestMock = new Mock>();
- PlexRequestMock.Setup(x => x.GetSettings()).Returns(new PlexRequestSettings());
- PlexRequestMock.Setup(x => x.GetSettingsAsync()).Returns(Task.FromResult(new PlexRequestSettings()));
- LandingPageMock.Setup(x => x.GetSettings()).Returns(new LandingPageSettings());
- Bootstrapper = new ConfigurableBootstrapper(with =>
- {
- with.Module();
- with.Dependency(PlexRequestMock.Object);
- with.Dependency(AuthMock.Object);
- with.Dependency(PlexMock.Object);
- with.Dependency(LandingPageMock.Object);
- with.RootPathProvider();
- });
- }
-
- [Test]
- public void LoginWithoutAuthentication()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = false, PlexAuthToken = "abc" };
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "abc");
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("abc"));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Never);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Never);
- }
-
- [Test]
- public void LoginWithoutAuthenticationWithEmptyUsername()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = false, PlexAuthToken = "abc" };
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
-
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", string.Empty);
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(false));
- AuthMock.Verify(x => x.GetSettings(), Times.Never);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Never);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Never);
- }
-
- [Test]
- public void LoginWithUsernameSuccessfully()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = true, PlexAuthToken = "abc" };
- var plexFriends = new PlexFriends
- {
- User = new[]
- {
- new UserFriends
- {
- Title = "abc",
- },
- }
- };
-
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(plexFriends);
- PlexMock.Setup(x => x.GetAccount(It.IsAny())).Returns(new PlexAccount());
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "abc");
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("abc"));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Never);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- }
-
- [Test]
- public void LoginWithUsernameUnSuccessfully()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = true, PlexAuthToken = "abc" };
- var plexFriends = new PlexFriends
- {
- User = new[]
- {
- new UserFriends
- {
- Username = "aaaa",
- },
- }
- };
-
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(plexFriends);
- PlexMock.Setup(x => x.GetAccount(It.IsAny())).Returns(new PlexAccount());
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
-
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "abc");
- });
-
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.Null);
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(false));
- Assert.That(body.Message, Is.Not.Empty);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Never);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- }
-
- [Test]
- public void LoginWithUsernameAndPasswordSuccessfully()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = true, UsePassword = true, PlexAuthToken = "abc" };
- var plexFriends = new PlexFriends
- {
- User = new[]
- {
- new UserFriends
- {
- Title = "abc",
- }
- }
- };
- var plexAuth = new PlexAuthentication
- {
- user = new User
- {
- authentication_token = "abc"
- }
- };
-
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(plexFriends);
- PlexMock.Setup(x => x.SignIn(It.IsAny(), It.IsAny())).Returns(plexAuth);
- PlexMock.Setup(x => x.GetAccount(It.IsAny())).Returns(new PlexAccount());
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "abc");
- with.FormValue("Password", "abc");
- });
-
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("abc"));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Once);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- }
-
- [Test]
- public void LoginWithUsernameAndPasswordUnSuccessfully()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = true, UsePassword = true, PlexAuthToken = "abc" };
- var plexFriends = new PlexFriends
- {
- User = new[]
- {
- new UserFriends
- {
- Username = "abc",
- },
- }
- };
- var plexAuth = new PlexAuthentication
- {
- user = null
- };
-
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(plexFriends);
- PlexMock.Setup(x => x.SignIn(It.IsAny(), It.IsAny())).Returns(plexAuth);
-
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "abc");
- with.FormValue("Password", "abc");
- });
-
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.Null);
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(false));
- Assert.That(body.Message, Is.Not.Empty);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Once);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Never);
- }
-
- [Test]
- public void AttemptToLoginAsDeniedUser()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = false, DeniedUsers = "abc", PlexAuthToken = "abc" };
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "abc");
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.Null);
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(false));
- Assert.That(body.Message, Is.Not.Empty);
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Never);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Never);
- }
-
- [Test]
- public void Logout()
- {
- Bootstrapper.WithSession(new Dictionary { { SessionKeys.UsernameKey, "abc" } });
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Get("/userlogin/logout", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- });
-
- Assert.That(HttpStatusCode.SeeOther, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.Null);
- }
-
- [Test]
- public void LoginWithOwnerUsernameSuccessfully()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = true, PlexAuthToken = "abc" };
- var plexFriends = new PlexFriends
- {
- User = new[]
- {
- new UserFriends()
- }
- };
-
- var account = new PlexAccount { Username = "Jamie" };
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(plexFriends);
- PlexMock.Setup(x => x.GetAccount(It.IsAny())).Returns(account);
- PlexMock.Setup(x => x.SignIn(It.IsAny(), It.IsAny())).Returns(new PlexAuthentication { user = new User { username = "Jamie" } });
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "Jamie");
- });
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("Jamie"));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny(), It.IsAny()), Times.Never);
- PlexMock.Verify(x => x.GetUsers(It.IsAny()), Times.Once);
- }
-
- [Test]
- public void LoginWithOwnerUsernameAndPasswordSuccessfully()
- {
- var expectedSettings = new AuthenticationSettings { UserAuthentication = true, UsePassword = true, PlexAuthToken = "abc" };
- var plexFriends = new PlexFriends
- {
- User = new[]
- {
- new UserFriends()
- }
- };
- var plexAuth = new PlexAuthentication
- {
- user = new User
- {
- authentication_token = "abc",
- username = "Jamie"
- }
- };
-
- var account = new PlexAccount { Username = "Jamie" };
-
- AuthMock.Setup(x => x.GetSettings()).Returns(expectedSettings);
- PlexMock.Setup(x => x.GetUsers(It.IsAny())).Returns(plexFriends);
- PlexMock.Setup(x => x.SignIn(It.IsAny(), It.IsAny())).Returns(plexAuth);
- PlexMock.Setup(x => x.GetAccount(It.IsAny())).Returns(account);
-
- Bootstrapper.WithSession(new Dictionary());
-
- var browser = new Browser(Bootstrapper);
- var result = browser.Post("/userlogin", with =>
- {
- with.HttpRequest();
- with.Header("Accept", "application/json");
- with.FormValue("Username", "jamie");
- with.FormValue("Password", "abc");
- });
-
-
- Assert.That(HttpStatusCode.OK, Is.EqualTo(result.StatusCode));
- Assert.That(result.Context.Request.Session[SessionKeys.UsernameKey], Is.EqualTo("jamie"));
-
- var body = JsonConvert.DeserializeObject(result.Body.AsString());
- Assert.That(body.Result, Is.EqualTo(true));
- AuthMock.Verify(x => x.GetSettings(), Times.Once);
- PlexMock.Verify(x => x.SignIn(It.IsAny