mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	Merge pull request #6025 from daullmer/localization-test
This commit is contained in:
		
						commit
						0216c452f1
					
				@ -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,22 +61,19 @@ 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))
 | 
					                await using var str = _assembly.GetManifestResourceStream(resource);
 | 
				
			||||||
                using (var reader = new StreamReader(str))
 | 
					                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))
 | 
				
			||||||
@ -95,7 +95,6 @@ namespace Emby.Server.Implementations.Localization
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _allParentalRatings[countryCode] = dict;
 | 
					                _allParentalRatings[countryCode] = dict;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -114,11 +113,8 @@ 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";
 | 
					            await using var stream = _assembly.GetManifestResourceStream(CulturesPath);
 | 
				
			||||||
 | 
					            using var reader = new StreamReader(stream);
 | 
				
			||||||
            using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
 | 
					 | 
				
			||||||
            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))
 | 
				
			||||||
@ -161,7 +157,6 @@ namespace Emby.Server.Implementations.Localization
 | 
				
			|||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _cultures = list;
 | 
					            _cultures = list;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -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,8 +345,7 @@ 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 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 (stream != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -367,7 +361,6 @@ namespace Emby.Server.Implementations.Localization
 | 
				
			|||||||
                _logger.LogError("Missing translation/culture resource: {ResourcePath}", resourcePath);
 | 
					                _logger.LogError("Missing translation/culture resource: {ResourcePath}", resourcePath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static string GetResourceFilename(string culture)
 | 
					        private static string GetResourceFilename(string culture)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
@ -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>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user