Kavita/API.Tests/Helpers/BrowserHelperTests.cs
Joe Milazzo 9f29fa593d
Progress Overhaul + Profile Page and a LOT more! (#4262)
Co-authored-by: Amelia <77553571+Fesaa@users.noreply.github.com>
Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
2025-12-09 10:00:11 -07:00

227 lines
11 KiB
C#

using API.Constants;
using API.Entities.Enums;
using API.Helpers;
using Xunit;
namespace API.Tests.Helpers;
public class BrowserHelperTests
{
#region DetermineClientType Tests
[Theory]
[InlineData("", ClientDeviceType.Unknown)]
[InlineData(null, ClientDeviceType.Unknown)]
public void DetermineClientType_ReturnsUnknown_ForEmptyOrNullUserAgent(string userAgent, ClientDeviceType expected)
{
var result = BrowserHelper.DetermineClientType(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (Linux; Android 11; Pixel 5) KOReader/2023.10", ClientDeviceType.KoReader)]
[InlineData("koreader/1.0", ClientDeviceType.KoReader)]
[InlineData("KOREADER", ClientDeviceType.KoReader)]
[InlineData("Mozilla/5.0 (Linux; U; Android 2.0; en-us;) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 (Kobo Touch)", ClientDeviceType.KoReader)]
public void DetermineClientType_ReturnsKOReader_ForKOReaderUserAgents(string userAgent, ClientDeviceType expected)
{
var result = BrowserHelper.DetermineClientType(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Panels/2.0", ClientDeviceType.Panels)]
[InlineData("panels", ClientDeviceType.Panels)]
public void DetermineClientType_ReturnsPanels_ForPanelsUserAgents(string userAgent, ClientDeviceType expected)
{
var result = BrowserHelper.DetermineClientType(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")]
[InlineData("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0")]
[InlineData("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15")]
[InlineData("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0")]
public void DetermineClientType_ReturnsWebBrowser_ForBrowserUserAgents(string userAgent)
{
var result = BrowserHelper.DetermineClientType(userAgent);
Assert.Equal(ClientDeviceType.WebBrowser, result);
}
[Theory]
[InlineData("curl/7.68.0")]
[InlineData("PostmanRuntime/7.32.3")]
[InlineData("SomeCustomClient/1.0")]
public void DetermineClientType_ReturnsUnknown_ForUnrecognizedUserAgents(string userAgent)
{
var result = BrowserHelper.DetermineClientType(userAgent);
Assert.Equal(ClientDeviceType.Unknown, result);
}
[Fact]
public void DetermineClientType_PrioritizesSpecificClients_OverWebBrowser()
{
// KOReader running on Android with Chrome-like UA
var userAgent = "Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36 Chrome/91.0 KOReader/2023.10";
var result = BrowserHelper.DetermineClientType(userAgent);
Assert.Equal(ClientDeviceType.KoReader, result);
}
#endregion
#region DetectPlatform Tests
[Theory]
[InlineData("", ClientDevicePlatform.Unknown)]
[InlineData(null, ClientDevicePlatform.Unknown)]
public void DetectPlatform_ReturnsUnknown_ForEmptyOrNullUserAgent(string userAgent, ClientDevicePlatform expected)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", ClientDevicePlatform.Windows)]
[InlineData("Mozilla/5.0 (Windows NT 6.1; WOW64)", ClientDevicePlatform.Windows)]
[InlineData("Mozilla/5.0 (win32)", ClientDevicePlatform.Windows)]
[InlineData("Mozilla/5.0 (win64)", ClientDevicePlatform.Windows)]
[InlineData("WINDOWS", ClientDevicePlatform.Windows)]
public void DetectPlatform_ReturnsWindows_ForWindowsUserAgents(string userAgent, ClientDevicePlatform expected)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15", ClientDevicePlatform.MacOs)]
[InlineData("Mozilla/5.0 (Macintosh; Intel Mac OS X 11_6) AppleWebKit/537.36", ClientDevicePlatform.MacOs)]
[InlineData("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15", ClientDevicePlatform.MacOs)]
[InlineData("macintosh", ClientDevicePlatform.MacOs)]
public void DetectPlatform_ReturnsMacOS_ForMacOSUserAgents(string userAgent, ClientDevicePlatform expected)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", ClientDevicePlatform.Linux)]
[InlineData("Mozilla/5.0 (X11; Ubuntu; Linux x86_64)", ClientDevicePlatform.Linux)]
[InlineData("linux", ClientDevicePlatform.Linux)]
[InlineData("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0", ClientDevicePlatform.Linux)]
public void DetectPlatform_ReturnsLinux_ForLinuxUserAgents(string userAgent, ClientDevicePlatform expected)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15", ClientDevicePlatform.Ios)]
[InlineData("Mozilla/5.0 (iPad; CPU OS 17_2 like Mac OS X) AppleWebKit/605.1.15", ClientDevicePlatform.Ios)]
[InlineData("Mozilla/5.0 (iPod touch; CPU iPhone OS 12_0 like Mac OS X)", ClientDevicePlatform.Ios)]
[InlineData("Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1", ClientDevicePlatform.Ios)]
[InlineData("Mozilla/5.0 (iPad; CPU OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1", ClientDevicePlatform.Ios)]
[InlineData("iphone", ClientDevicePlatform.Ios)]
[InlineData("ipad", ClientDevicePlatform.Ios)]
[InlineData("ipod", ClientDevicePlatform.Ios)]
[InlineData("mac os", ClientDevicePlatform.Ios)]
public void DetectPlatform_ReturnsIOS_ForIOSUserAgents(string userAgent, ClientDevicePlatform expected)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expected, result);
}
[Theory]
[InlineData("Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36", ClientDevicePlatform.Android)]
[InlineData("Mozilla/5.0 (Linux; Android 11; SM-G991B)", ClientDevicePlatform.Android)]
[InlineData("android", ClientDevicePlatform.Android)]
[InlineData("Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", ClientDevicePlatform.Android)]
[InlineData("Mozilla/5.0 (Linux; Android 15; SM-S931B Build/AP3A.240905.015.A2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36", ClientDevicePlatform.Android)]
public void DetectPlatform_ReturnsAndroid_ForAndroidUserAgents(string userAgent, ClientDevicePlatform expected)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expected, result);
}
[Fact]
public void DetectPlatform_ReturnsAndroid_NotLinux_ForAndroidUserAgents()
{
// Android UAs contain "Linux" but should be detected as Android
const string userAgent = "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36";
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(ClientDevicePlatform.Android, result);
}
[Theory]
[InlineData("curl/7.68.0")]
[InlineData("PostmanRuntime/7.32.3")]
[InlineData("FreeBSD")]
[InlineData("OpenBSD")]
public void DetectPlatform_ReturnsUnknown_ForUnrecognizedPlatforms(string userAgent)
{
var result = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(ClientDevicePlatform.Unknown, result);
}
[Fact]
public void DetectPlatform_IsCaseInsensitive()
{
Assert.Equal(ClientDevicePlatform.Windows, BrowserHelper.DetectPlatform("WINDOWS NT 10.0"));
Assert.Equal(ClientDevicePlatform.Android, BrowserHelper.DetectPlatform("ANDROID 13"));
Assert.Equal(ClientDevicePlatform.MacOs, BrowserHelper.DetectPlatform("MACINTOSH; INTEL MAC OS X"));
Assert.Equal(ClientDevicePlatform.Ios, BrowserHelper.DetectPlatform("IPHONE"));
Assert.Equal(ClientDevicePlatform.Linux, BrowserHelper.DetectPlatform("LINUX X86_64"));
}
#endregion
#region Real-World User Agent Tests
[Theory]
[InlineData(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.Windows)]
[InlineData(
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.MacOs)]
[InlineData(
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.Linux)]
[InlineData(
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.Ios)]
[InlineData(
"Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.Android)]
[InlineData(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.Windows)]
[InlineData(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
ClientDeviceType.WebBrowser,
ClientDevicePlatform.Windows)]
[InlineData(
"Mozilla/5.0 (X11; Linux x86_64; Librera) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2997.373167658 Safari/537.36",
ClientDeviceType.Librera,
ClientDevicePlatform.Linux)] // Should be Android but not sure how to actually correct
public void RealWorld_UserAgents_AreDetectedCorrectly(string userAgent, ClientDeviceType expectedClientType, ClientDevicePlatform expectedPlatform)
{
var clientType = BrowserHelper.DetermineClientType(userAgent);
var platform = BrowserHelper.DetectPlatform(userAgent);
Assert.Equal(expectedClientType, clientType);
Assert.Equal(expectedPlatform, platform);
}
#endregion
}