using System.Text; using Metin2Launcher.Runtime; using Xunit; namespace Metin2Launcher.Tests; public class RuntimeKeyTests { private const string ValidHex64 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; private static string SampleJson( string keyId = "2026.04.14-1", string master = ValidHex64, string pub = ValidHex64) => $$""" { "key_id": "{{keyId}}", "master_key_hex": "{{master}}", "sign_pubkey_hex": "{{pub}}" } """; [Fact] public void Parse_happy_path() { var rk = RuntimeKey.Parse(Encoding.UTF8.GetBytes(SampleJson())); Assert.Equal("2026.04.14-1", rk.KeyId); Assert.Equal(ValidHex64, rk.MasterKeyHex); Assert.Equal(ValidHex64, rk.SignPubkeyHex); } [Fact] public void Parse_rejects_missing_key_id() { var json = SampleJson(keyId: ""); Assert.Throws(() => RuntimeKey.Parse(Encoding.UTF8.GetBytes(json))); } [Theory] [InlineData("")] [InlineData("tooshort")] [InlineData("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz")] // right len, wrong chars public void Parse_rejects_bad_master_key(string master) { var json = SampleJson(master: master); Assert.Throws(() => RuntimeKey.Parse(Encoding.UTF8.GetBytes(json))); } [Fact] public void Parse_rejects_bad_pubkey() { var json = SampleJson(pub: new string('g', 64)); Assert.Throws(() => RuntimeKey.Parse(Encoding.UTF8.GetBytes(json))); } [Fact] public void Parse_accepts_uppercase_hex() { var upper = ValidHex64.ToUpperInvariant(); var rk = RuntimeKey.Parse(Encoding.UTF8.GetBytes(SampleJson(master: upper, pub: upper))); Assert.Equal(upper, rk.MasterKeyHex); } [Fact] public void Load_reads_from_disk() { var tmp = Path.Combine(Path.GetTempPath(), "runtime-key-test-" + Guid.NewGuid() + ".json"); File.WriteAllText(tmp, SampleJson()); try { var rk = RuntimeKey.Load(tmp); Assert.Equal("2026.04.14-1", rk.KeyId); } finally { File.Delete(tmp); } } [Fact] public void Parse_rejects_malformed_json() { Assert.Throws(() => RuntimeKey.Parse(Encoding.UTF8.GetBytes("not json"))); } }