/* * Copyright (c) 2026 Proton AG * * This file is part of ProtonVPN. * * ProtonVPN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProtonVPN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProtonVPN. If not, see . */ using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using ProtonVPN.Client.Localization.Tests.Helpers; namespace ProtonVPN.Client.Localization.Tests; [TestClass] public class ResourceKeyValidationTests { /// /// Keys matching these prefixes are excluded from the "unused keys" check /// private static readonly string[] _dynamicKeyPrefixes = { "Country_val_", "Settings_Theme_", "Settings_Connection_Default_", "Settings_SelectedProtocol_", }; [TestMethod] [Ignore("Temporarily disabled. Enable when required.")] public void EnUsResw_ShouldNotContainDuplicateValues() { Dictionary> duplicates = ReswFileParser.GetDuplicateValues(SourcePathResolver.EnUsReswPath); List violations = duplicates .OrderBy(kv => kv.Key) .Select(kv => $"\"{kv.Key}\" is shared by: {string.Join(", ", kv.Value)}") .ToList(); violations.Should().BeEmpty( $"Found {duplicates.Count} duplicated value(s):\n" + string.Join("\n", violations.Select(v => $" • {v}"))); } [TestMethod] public void EnUsResw_ShouldNotContainUnusedKeys() { HashSet definedKeys = ReswFileParser.GetResourceKeys(SourcePathResolver.EnUsReswPath); HashSet referencedKeys = SourceKeyScanner.CollectReferencedKeys(SourcePathResolver.SourceRoot, definedKeys); List unusedKeys = definedKeys .Where(key => !IsKeyReferencedOrDynamic(key, referencedKeys)) .OrderBy(k => k) .ToList(); unusedKeys.Should().BeEmpty( $"Found {unusedKeys.Count} unused key(s):\n" + string.Join("\n", unusedKeys.Select(k => $" • {k}"))); } private static bool IsKeyReferencedOrDynamic(string key, HashSet referencedKeys) { if (referencedKeys.Contains(key)) { return true; } foreach (string prefix in _dynamicKeyPrefixes) { if (key.StartsWith(prefix, StringComparison.Ordinal)) { return true; } } return PluralKeyHelper.IsPluralVariantOfReferencedKey(key, referencedKeys); } }