From 8a58140f9b0794d6d344fe2ac5f22449d96d65af Mon Sep 17 00:00:00 2001 From: Dev Date: Thu, 2 Apr 2026 12:14:49 +0200 Subject: [PATCH] test(01-05): add failing tests for TranslationSource singleton - Instance singleton test - EN string lookup test - FR culture fallback test - Missing key returns bracketed key - PropertyChanged fires with empty string on culture switch - Same culture does not fire PropertyChanged --- .../Localization/TranslationSourceTests.cs | 82 ++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/SharepointToolbox.Tests/Localization/TranslationSourceTests.cs b/SharepointToolbox.Tests/Localization/TranslationSourceTests.cs index 8584da1..9335d8a 100644 --- a/SharepointToolbox.Tests/Localization/TranslationSourceTests.cs +++ b/SharepointToolbox.Tests/Localization/TranslationSourceTests.cs @@ -1,7 +1,83 @@ +using SharepointToolbox.Localization; +using System.ComponentModel; +using System.Globalization; + namespace SharepointToolbox.Tests.Localization; -public class TranslationSourceTests +[Trait("Category", "Unit")] +public class TranslationSourceTests : IDisposable { - [Fact(Skip = "Wave 0 stub — implemented in plan 01-05")] - public void ChangeLanguage_Updates_Bound_Strings() { } + private readonly CultureInfo _originalCulture; + + public TranslationSourceTests() + { + _originalCulture = TranslationSource.Instance.CurrentCulture; + // Reset to EN before each test + TranslationSource.Instance.CurrentCulture = new CultureInfo("en-US"); + } + + public void Dispose() + { + // Restore original culture after each test to prevent test pollution + TranslationSource.Instance.CurrentCulture = _originalCulture; + } + + [Fact] + public void Instance_IsSameInstance_OnMultipleAccesses() + { + var instance1 = TranslationSource.Instance; + var instance2 = TranslationSource.Instance; + Assert.Same(instance1, instance2); + } + + [Fact] + public void Indexer_ReturnsEnString_ForEnCulture() + { + TranslationSource.Instance.CurrentCulture = new CultureInfo("en-US"); + var result = TranslationSource.Instance["app.title"]; + Assert.Equal("SharePoint Toolbox", result); + } + + [Fact] + public void Indexer_ReturnsFrOrFallback_AfterSwitchToFrFR() + { + TranslationSource.Instance.CurrentCulture = new CultureInfo("fr-FR"); + var result = TranslationSource.Instance["app.title"]; + // FR stub uses EN text — at minimum should not be null or empty + Assert.NotNull(result); + Assert.NotEmpty(result); + Assert.DoesNotContain("[", result); // Should not be missing-key placeholder + } + + [Fact] + public void Indexer_ReturnsBracketedKey_ForMissingKey() + { + var result = TranslationSource.Instance["key.does.not.exist"]; + Assert.Equal("[key.does.not.exist]", result); + } + + [Fact] + public void ChangingCurrentCulture_FiresPropertyChanged_WithEmptyPropertyName() + { + string? capturedPropertyName = null; + TranslationSource.Instance.PropertyChanged += (sender, args) => + capturedPropertyName = args.PropertyName; + + TranslationSource.Instance.CurrentCulture = new CultureInfo("fr-FR"); + + Assert.Equal(string.Empty, capturedPropertyName); + } + + [Fact] + public void SettingSameCulture_DoesNotFirePropertyChanged() + { + TranslationSource.Instance.CurrentCulture = new CultureInfo("en-US"); + int fireCount = 0; + TranslationSource.Instance.PropertyChanged += (sender, args) => fireCount++; + + // Set the exact same culture + TranslationSource.Instance.CurrentCulture = new CultureInfo("en-US"); + + Assert.Equal(0, fireCount); + } }