Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix localization rule \Localization\[CultureName]\[ModuleId].po #16419

Merged
merged 24 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ node_modules/

wwwroot
**/Localization/**/*.po
!test/OrchardCore.Tests/Localization/**/*.po
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

@hyzx86 hyzx86 Jul 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must do this, or you will lose the PO files. You can try it.

!src/OrchardCore.Modules/**/wwwroot
!src/OrchardCore.Themes/**/wwwroot
!src/OrchardCore.Modules/**/Localization/**/*.po
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public IEnumerable<IFileInfo> 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
Expand Down
55 changes: 53 additions & 2 deletions test/OrchardCore.Tests/Localization/LocalizationManagerTests.cs
Original file line number Diff line number Diff line change
@@ -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
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
{
Expand Down Expand Up @@ -43,7 +48,7 @@ public void GetDictionaryReturnsDictionaryWithTranslationsFromProvider()
.Setup(o => o.LoadTranslations(It.Is<string>(culture => culture == "cs"), It.IsAny<CultureDictionary>()))
.Callback<string, CultureDictionary>((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" };
Expand All @@ -67,11 +72,57 @@ public void GetDictionarySelectsPluralRuleFromProviderWithHigherPriority()
It.IsAny<CultureDictionary>())
);

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", "你好!")]
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
public async Task TestLocalizationRule(string culture, string expected)
{
var context = new SiteContext();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a functional test, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand what you mean. I think this is the closest test to the actual operation.

await context.InitializeAsync();

await context.UsingTenantScopeAsync(async scope =>
{
var shellFeaturesManager = scope.ServiceProvider.GetRequiredService<IShellFeaturesManager>();
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<ISiteService>();
var siteSettings = await siteService.LoadSiteSettingsAsync();

siteSettings.Alter<LocalizationSettings>("LocalizationSettings", localizationSettings =>
{
localizationSettings.DefaultCulture = culture;
localizationSettings.SupportedCultures = [culture];
});

await siteService.UpdateSiteSettingsAsync(siteSettings);

var shellSettings = scope.ServiceProvider.GetRequiredService<ShellSettings>();
var shellHost = scope.ServiceProvider.GetRequiredService<IShellHost>();

await shellHost.ReleaseShellContextAsync(shellSettings);
});

await context.UsingTenantScopeAsync(scope =>
{
using var cultureScope = CultureScope.Create(culture, culture);
var localizer = scope.ServiceProvider.GetRequiredService<IStringLocalizer<LocalizationManagerTests>>();

// Assert
Assert.Equal(expected, localizer["hello!"]);

return Task.CompletedTask;
});
}
}
}
3 changes: 3 additions & 0 deletions test/OrchardCore.Tests/Localization/en/OrchardCore.Tests.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
msgctxt "OrchardCore.Tests.Localization.LocalizationManagerTests"
msgid "hello!"
msgstr "Hello en !"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
msgctxt "OrchardCore.Tests.Localization.LocalizationManagerTests"
msgid "hello!"
msgstr "你好!"
6 changes: 6 additions & 0 deletions test/OrchardCore.Tests/OrchardCore.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>

<ItemGroup>
<None Update="Localization\*\OrchardCore.Tests.po">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

Comment on lines +83 to +88
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need, you can add them as embedded resources

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to preserve the newest?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the target rule needs to copy it to the output directory.

<Import Project="..\..\src\OrchardCore.Build\OrchardCore.Commons.targets" />

</Project>