diff --git a/.gitignore b/.gitignore index 2db89d394e0..e82568c0a66 100644 --- a/.gitignore +++ b/.gitignore @@ -195,6 +195,7 @@ node_modules/ wwwroot **/Localization/**/*.po +!test/OrchardCore.Tests/Localization/**/*.po !src/OrchardCore.Modules/**/wwwroot !src/OrchardCore.Themes/**/wwwroot !src/OrchardCore.Modules/**/Localization/**/*.po diff --git a/src/OrchardCore.Modules/OrchardCore.Localization/ModularPoFileLocationProvider.cs b/src/OrchardCore.Modules/OrchardCore.Localization/ModularPoFileLocationProvider.cs index 4ba639c56bb..75fc3abdda3 100644 --- a/src/OrchardCore.Modules/OrchardCore.Localization/ModularPoFileLocationProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Localization/ModularPoFileLocationProvider.cs @@ -74,6 +74,9 @@ public IEnumerable GetLocations(string cultureName) // \src\OrchardCore.Cms.Web\Localization\OrchardCore.Cms.Web-fr-CA.po yield return _fileProvider.GetFileInfo(PathExtensions.Combine(_resourcesContainer, extension.Id + CultureDelimiter + poFileName)); + + // \Localization\[CultureName]\[ModuleId].po + yield return new PhysicalFileInfo(new FileInfo(PathExtensions.Combine(_resourcesContainer, cultureName, extension.Id + PoFileExtension))); } // Load all .po files from a culture specific folder diff --git a/test/OrchardCore.Tests/Localization/LocalizationManagerTests.cs b/test/OrchardCore.Tests/Localization/LocalizationManagerTests.cs index bcd3aa1f005..83dfede050d 100644 --- a/test/OrchardCore.Tests/Localization/LocalizationManagerTests.cs +++ b/test/OrchardCore.Tests/Localization/LocalizationManagerTests.cs @@ -1,4 +1,9 @@ +using OrchardCore.Entities; +using OrchardCore.Environment.Shell; using OrchardCore.Localization; +using OrchardCore.Localization.Models; +using OrchardCore.Settings; +using OrchardCore.Tests.Apis.Context; namespace OrchardCore.Tests.Localization; @@ -43,7 +48,7 @@ public void GetDictionaryReturnsDictionaryWithTranslationsFromProvider() .Setup(o => o.LoadTranslations(It.Is(culture => culture == "cs"), It.IsAny())) .Callback((culture, dictioanry) => dictioanry.MergeTranslations(new[] { dictionaryRecord })); - var manager = new LocalizationManager(new[] { _pluralRuleProvider.Object }, new[] { _translationProvider.Object }, _memoryCache); + var manager = new LocalizationManager([_pluralRuleProvider.Object], [_translationProvider.Object], _memoryCache); var dictionary = manager.GetDictionary(CultureInfo.GetCultureInfo("cs")); var key = new CultureDictionaryRecordKey { MessageId = "ball" }; @@ -67,10 +72,56 @@ public void GetDictionarySelectsPluralRuleFromProviderWithHigherPriority() It.IsAny()) ); - var manager = new LocalizationManager(new[] { _pluralRuleProvider.Object, highPriorityRuleProvider.Object }, new[] { _translationProvider.Object }, _memoryCache); + var manager = new LocalizationManager([_pluralRuleProvider.Object, highPriorityRuleProvider.Object], [_translationProvider.Object], _memoryCache); var dictionary = manager.GetDictionary(CultureInfo.GetCultureInfo("cs")); Assert.Equal(dictionary.PluralRule, csPluralRuleOverride); } + + [Theory] + [InlineData("en", "Hello en !")] + [InlineData("zh-CN", "你好!")] + public async Task TestLocalizationRule(string culture, string expected) + { + var context = new SiteContext(); + await context.InitializeAsync(); + + await context.UsingTenantScopeAsync(async scope => + { + var shellFeaturesManager = scope.ServiceProvider.GetRequiredService(); + var availableFeatures = await shellFeaturesManager.GetAvailableFeaturesAsync(); + var featureIds = new string[] { "OrchardCore.Localization.ContentLanguageHeader", "OrchardCore.Localization" }; + var features = availableFeatures.Where(feature => featureIds.Contains(feature.Id)); + + await shellFeaturesManager.EnableFeaturesAsync(features, true); + + var siteService = scope.ServiceProvider.GetRequiredService(); + var siteSettings = await siteService.LoadSiteSettingsAsync(); + + siteSettings.Alter("LocalizationSettings", localizationSettings => + { + localizationSettings.DefaultCulture = culture; + localizationSettings.SupportedCultures = [culture]; + }); + + await siteService.UpdateSiteSettingsAsync(siteSettings); + + var shellSettings = scope.ServiceProvider.GetRequiredService(); + var shellHost = scope.ServiceProvider.GetRequiredService(); + + await shellHost.ReleaseShellContextAsync(shellSettings); + }); + + await context.UsingTenantScopeAsync(scope => + { + using var cultureScope = CultureScope.Create(culture, culture); + var localizer = scope.ServiceProvider.GetRequiredService>(); + + // Assert + Assert.Equal(expected, localizer["hello!"]); + + return Task.CompletedTask; + }); + } } diff --git a/test/OrchardCore.Tests/Localization/en/OrchardCore.Tests.po b/test/OrchardCore.Tests/Localization/en/OrchardCore.Tests.po new file mode 100644 index 00000000000..7a17dd942c4 --- /dev/null +++ b/test/OrchardCore.Tests/Localization/en/OrchardCore.Tests.po @@ -0,0 +1,3 @@ +msgctxt "OrchardCore.Tests.Localization.LocalizationManagerTests" +msgid "hello!" +msgstr "Hello en !" diff --git a/test/OrchardCore.Tests/Localization/zh-CN/OrchardCore.Tests.po b/test/OrchardCore.Tests/Localization/zh-CN/OrchardCore.Tests.po new file mode 100644 index 00000000000..63865b3c7ae --- /dev/null +++ b/test/OrchardCore.Tests/Localization/zh-CN/OrchardCore.Tests.po @@ -0,0 +1,3 @@ +msgctxt "OrchardCore.Tests.Localization.LocalizationManagerTests" +msgid "hello!" +msgstr "你好!" diff --git a/test/OrchardCore.Tests/OrchardCore.Tests.csproj b/test/OrchardCore.Tests/OrchardCore.Tests.csproj index 519888f4cba..e654abd7848 100644 --- a/test/OrchardCore.Tests/OrchardCore.Tests.csproj +++ b/test/OrchardCore.Tests/OrchardCore.Tests.csproj @@ -80,6 +80,12 @@ + + + PreserveNewest + + +