瀏覽代碼

Merge pull request #6025 from daullmer/localization-test

Claus Vium 4 年之前
父節點
當前提交
0216c452f1

+ 67 - 74
Emby.Server.Implementations/Localization/LocalizationManager.cs

@@ -23,6 +23,9 @@ namespace Emby.Server.Implementations.Localization
     public class LocalizationManager : ILocalizationManager
     public class LocalizationManager : ILocalizationManager
     {
     {
         private const string DefaultCulture = "en-US";
         private const string DefaultCulture = "en-US";
+        private const string RatingsPath = "Emby.Server.Implementations.Localization.Ratings.";
+        private const string CulturesPath = "Emby.Server.Implementations.Localization.iso6392.txt";
+        private const string CountriesPath = "Emby.Server.Implementations.Localization.countries.json";
         private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
         private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
         private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
         private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
 
 
@@ -58,43 +61,39 @@ namespace Emby.Server.Implementations.Localization
         /// <returns><see cref="Task" />.</returns>
         /// <returns><see cref="Task" />.</returns>
         public async Task LoadAll()
         public async Task LoadAll()
         {
         {
-            const string RatingsResource = "Emby.Server.Implementations.Localization.Ratings.";
-
             // Extract from the assembly
             // Extract from the assembly
             foreach (var resource in _assembly.GetManifestResourceNames())
             foreach (var resource in _assembly.GetManifestResourceNames())
             {
             {
-                if (!resource.StartsWith(RatingsResource, StringComparison.Ordinal))
+                if (!resource.StartsWith(RatingsPath, StringComparison.Ordinal))
                 {
                 {
                     continue;
                     continue;
                 }
                 }
 
 
-                string countryCode = resource.Substring(RatingsResource.Length, 2);
+                string countryCode = resource.Substring(RatingsPath.Length, 2);
                 var dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
                 var dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
 
 
-                using (var str = _assembly.GetManifestResourceStream(resource))
-                using (var reader = new StreamReader(str))
+                await using var str = _assembly.GetManifestResourceStream(resource);
+                using var reader = new StreamReader(str);
+                await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
                 {
                 {
-                    await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
+                    if (string.IsNullOrWhiteSpace(line))
                     {
                     {
-                        if (string.IsNullOrWhiteSpace(line))
-                        {
-                            continue;
-                        }
-
-                        string[] parts = line.Split(',');
-                        if (parts.Length == 2
-                            && int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var value))
-                        {
-                            var name = parts[0];
-                            dict.Add(name, new ParentalRating(name, value));
-                        }
+                        continue;
+                    }
+
+                    string[] parts = line.Split(',');
+                    if (parts.Length == 2
+                        && int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var value))
+                    {
+                        var name = parts[0];
+                        dict.Add(name, new ParentalRating(name, value));
+                    }
 #if DEBUG
 #if DEBUG
-                        else
-                        {
-                            _logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode);
-                        }
-#endif
+                    else
+                    {
+                        _logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode);
                     }
                     }
+#endif
                 }
                 }
 
 
                 _allParentalRatings[countryCode] = dict;
                 _allParentalRatings[countryCode] = dict;
@@ -114,52 +113,48 @@ namespace Emby.Server.Implementations.Localization
         {
         {
             List<CultureDto> list = new List<CultureDto>();
             List<CultureDto> list = new List<CultureDto>();
 
 
-            const string ResourcePath = "Emby.Server.Implementations.Localization.iso6392.txt";
-
-            using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
-            using (var reader = new StreamReader(stream))
+            await using var stream = _assembly.GetManifestResourceStream(CulturesPath);
+            using var reader = new StreamReader(stream);
+            await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
             {
             {
-                await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
+                if (string.IsNullOrWhiteSpace(line))
                 {
                 {
-                    if (string.IsNullOrWhiteSpace(line))
+                    continue;
+                }
+
+                var parts = line.Split('|');
+
+                if (parts.Length == 5)
+                {
+                    string name = parts[3];
+                    if (string.IsNullOrWhiteSpace(name))
                     {
                     {
                         continue;
                         continue;
                     }
                     }
 
 
-                    var parts = line.Split('|');
+                    string twoCharName = parts[2];
+                    if (string.IsNullOrWhiteSpace(twoCharName))
+                    {
+                        continue;
+                    }
 
 
-                    if (parts.Length == 5)
+                    string[] threeletterNames;
+                    if (string.IsNullOrWhiteSpace(parts[1]))
+                    {
+                        threeletterNames = new[] { parts[0] };
+                    }
+                    else
                     {
                     {
-                        string name = parts[3];
-                        if (string.IsNullOrWhiteSpace(name))
-                        {
-                            continue;
-                        }
-
-                        string twoCharName = parts[2];
-                        if (string.IsNullOrWhiteSpace(twoCharName))
-                        {
-                            continue;
-                        }
-
-                        string[] threeletterNames;
-                        if (string.IsNullOrWhiteSpace(parts[1]))
-                        {
-                            threeletterNames = new[] { parts[0] };
-                        }
-                        else
-                        {
-                            threeletterNames = new[] { parts[0], parts[1] };
-                        }
-
-                        list.Add(new CultureDto
-                        {
-                            DisplayName = name,
-                            Name = name,
-                            ThreeLetterISOLanguageNames = threeletterNames,
-                            TwoLetterISOLanguageName = twoCharName
-                        });
+                        threeletterNames = new[] { parts[0], parts[1] };
                     }
                     }
+
+                    list.Add(new CultureDto
+                    {
+                        DisplayName = name,
+                        Name = name,
+                        ThreeLetterISOLanguageNames = threeletterNames,
+                        TwoLetterISOLanguageName = twoCharName
+                    });
                 }
                 }
             }
             }
 
 
@@ -188,7 +183,7 @@ namespace Emby.Server.Implementations.Localization
         /// <inheritdoc />
         /// <inheritdoc />
         public IEnumerable<CountryInfo> GetCountries()
         public IEnumerable<CountryInfo> GetCountries()
         {
         {
-            using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
+            using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream(CountriesPath));
 
 
             return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
             return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
         }
         }
@@ -350,23 +345,21 @@ namespace Emby.Server.Implementations.Localization
 
 
         private async Task CopyInto(IDictionary<string, string> dictionary, string resourcePath)
         private async Task CopyInto(IDictionary<string, string> dictionary, string resourcePath)
         {
         {
-            using (var stream = _assembly.GetManifestResourceStream(resourcePath))
+            await using var stream = _assembly.GetManifestResourceStream(resourcePath);
+            // If a Culture doesn't have a translation the stream will be null and it defaults to en-us further up the chain
+            if (stream != null)
             {
             {
-                // If a Culture doesn't have a translation the stream will be null and it defaults to en-us further up the chain
-                if (stream != null)
-                {
-                    var dict = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(stream, _jsonOptions).ConfigureAwait(false);
+                var dict = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(stream, _jsonOptions).ConfigureAwait(false);
 
 
-                    foreach (var key in dict.Keys)
-                    {
-                        dictionary[key] = dict[key];
-                    }
-                }
-                else
+                foreach (var key in dict.Keys)
                 {
                 {
-                    _logger.LogError("Missing translation/culture resource: {ResourcePath}", resourcePath);
+                    dictionary[key] = dict[key];
                 }
                 }
             }
             }
+            else
+            {
+                _logger.LogError("Missing translation/culture resource: {ResourcePath}", resourcePath);
+            }
         }
         }
 
 
         private static string GetResourceFilename(string culture)
         private static string GetResourceFilename(string culture)

+ 179 - 0
tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs

@@ -0,0 +1,179 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Emby.Server.Implementations.Localization;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.Configuration;
+using Microsoft.Extensions.Logging.Abstractions;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Localization
+{
+    public class LocalizationManagerTests
+    {
+        [Fact]
+        public void GetCountries_All_Success()
+        {
+            var localizationManager = Setup(new ServerConfiguration
+            {
+                UICulture = "de-DE"
+            });
+            var countries = localizationManager.GetCountries().ToList();
+
+            Assert.Equal(139, countries.Count);
+
+            var germany = countries.FirstOrDefault(x => x.Name.Equals("DE", StringComparison.Ordinal));
+            Assert.NotNull(germany);
+            Assert.Equal("Germany", germany!.DisplayName);
+            Assert.Equal("DEU", germany.ThreeLetterISORegionName);
+            Assert.Equal("DE", germany.TwoLetterISORegionName);
+        }
+
+        [Fact]
+        public async Task GetCultures_All_Success()
+        {
+            var localizationManager = Setup(new ServerConfiguration
+            {
+                UICulture = "de-DE"
+            });
+            await localizationManager.LoadAll();
+            var cultures = localizationManager.GetCultures().ToList();
+
+            Assert.Equal(189, cultures.Count);
+
+            var germany = cultures.FirstOrDefault(x => x.TwoLetterISOLanguageName.Equals("de", StringComparison.Ordinal));
+            Assert.NotNull(germany);
+            Assert.Equal("ger", germany!.ThreeLetterISOLanguageName);
+            Assert.Equal("German", germany.DisplayName);
+            Assert.Equal("German", germany.Name);
+            Assert.Contains("deu", germany.ThreeLetterISOLanguageNames);
+            Assert.Contains("ger", germany.ThreeLetterISOLanguageNames);
+        }
+
+        [Theory]
+        [InlineData("de")]
+        [InlineData("ger")]
+        [InlineData("german")]
+        public async Task FindLanguageInfo_Valid_Success(string identifier)
+        {
+            var localizationManager = Setup(new ServerConfiguration
+            {
+                UICulture = "de-DE"
+            });
+            await localizationManager.LoadAll();
+
+            var germany = localizationManager.FindLanguageInfo(identifier);
+            Assert.NotNull(germany);
+
+            Assert.Equal("ger", germany.ThreeLetterISOLanguageName);
+            Assert.Equal("German", germany.DisplayName);
+            Assert.Equal("German", germany.Name);
+            Assert.Contains("deu", germany.ThreeLetterISOLanguageNames);
+            Assert.Contains("ger", germany.ThreeLetterISOLanguageNames);
+        }
+
+        [Fact]
+        public async Task GetParentalRatings_Default_Success()
+        {
+            var localizationManager = Setup(new ServerConfiguration
+            {
+                UICulture = "de-DE"
+            });
+            await localizationManager.LoadAll();
+            var ratings = localizationManager.GetParentalRatings().ToList();
+
+            Assert.Equal(23, ratings.Count);
+
+            var tvma = ratings.FirstOrDefault(x => x.Name.Equals("TV-MA", StringComparison.Ordinal));
+            Assert.NotNull(tvma);
+            Assert.Equal(9, tvma!.Value);
+        }
+
+        [Fact]
+        public async Task GetParentalRatings_ConfiguredCountryCode_Success()
+        {
+            var localizationManager = Setup(new ServerConfiguration()
+            {
+                MetadataCountryCode = "DE"
+            });
+            await localizationManager.LoadAll();
+            var ratings = localizationManager.GetParentalRatings().ToList();
+
+            Assert.Equal(10, ratings.Count);
+
+            var fsk = ratings.FirstOrDefault(x => x.Name.Equals("FSK-12", StringComparison.Ordinal));
+            Assert.NotNull(fsk);
+            Assert.Equal(7, fsk!.Value);
+        }
+
+        [Theory]
+        [InlineData("CA-R", "CA", 10)]
+        [InlineData("FSK-16", "DE", 8)]
+        [InlineData("FSK-18", "DE", 9)]
+        [InlineData("FSK-18", "US", 9)]
+        [InlineData("TV-MA", "US", 9)]
+        [InlineData("XXX", "asdf", 100)]
+        [InlineData("Germany: FSK-18", "DE", 9)]
+        public async Task GetRatingLevel_GivenValidString_Success(string value, string countryCode, int expectedLevel)
+        {
+            var localizationManager = Setup(new ServerConfiguration()
+            {
+                MetadataCountryCode = countryCode
+            });
+            await localizationManager.LoadAll();
+            var level = localizationManager.GetRatingLevel(value);
+            Assert.NotNull(level);
+            Assert.Equal(expectedLevel, level!);
+        }
+
+        [Fact]
+        public async Task GetRatingLevel_GivenUnratedString_Success()
+        {
+            var localizationManager = Setup(new ServerConfiguration()
+            {
+                UICulture = "de-DE"
+            });
+            await localizationManager.LoadAll();
+            Assert.Null(localizationManager.GetRatingLevel("n/a"));
+        }
+
+        [Theory]
+        [InlineData("Default", "Default")]
+        [InlineData("HeaderLiveTV", "Live TV")]
+        public void GetLocalizedString_Valid_Success(string key, string expected)
+        {
+            var localizationManager = Setup(new ServerConfiguration()
+            {
+                UICulture = "en-US"
+            });
+
+            var translated = localizationManager.GetLocalizedString(key);
+            Assert.NotNull(translated);
+            Assert.Equal(expected, translated);
+        }
+
+        [Fact]
+        public void GetLocalizedString_Invalid_Success()
+        {
+            var localizationManager = Setup(new ServerConfiguration()
+            {
+                UICulture = "en-US"
+            });
+
+            var key = "SuperInvalidTranslationKeyThatWillNeverBeAdded";
+
+            var translated = localizationManager.GetLocalizedString(key);
+            Assert.NotNull(translated);
+            Assert.Equal(key, translated);
+        }
+
+        private LocalizationManager Setup(ServerConfiguration config)
+        {
+            var mockConfiguration = new Mock<IServerConfigurationManager>();
+            mockConfiguration.SetupGet(x => x.Configuration).Returns(config);
+
+            return new LocalizationManager(mockConfiguration.Object, new NullLogger<LocalizationManager>());
+        }
+    }
+}