namespace sockeye.tests; /* Extract key fixture data, note that pgroup / format is 1 for v7 product family keys and not 1 for any v8 family keys mkdir C:\data\sockeye-fixtures $env:PGCLIENTENCODING = "UTF8" .\psql -U postgres -d sockeye -At -o C:\data\sockeye-fixtures\resign.json -c " SELECT json_agg(t ORDER BY t.id) FROM ( SELECT id, pgroup AS format, key FROM alicense WHERE key IS NOT NULL ) t;" */ // public class UnitTest1 // { // [Fact] // public void Test1() // { // } // } using System.Text.Json; public record ResignRow(long Id, int Format, string Key); public static class ResignFixture { static readonly Lazy> _rows = new(Load); public static IReadOnlyDictionary Rows => _rows.Value; static Dictionary Load() { var path = "C:\\data\\sockeye-fixtures\\resign.json";//Environment.GetEnvironmentVariable("SOCKEYE_RESIGN_FIXTURE"); if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) throw new InvalidOperationException( "Set SOCKEYE_RESIGN_FIXTURE to the exported alicense JSON file."); var rows = JsonSerializer.Deserialize>( File.ReadAllText(path), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return rows.ToDictionary(r => r.Id); } } public class ResignTests { public static IEnumerable RowIds() => ResignFixture.Rows.Keys.Select(id => new object[] { id }); [Theory] [MemberData(nameof(RowIds))] public void Stored_licence_resigns_identically(long id) { var row = ResignFixture.Rows[id]; var keyText = Between(row.Key, "[KEY", "KEY]"); var expected = StripWs(Between(row.Key, "[SIGNATURE", "SIGNATURE]")); var actual = row.Format == 1 ? Sockeye.Biz.KeyFactory.Sign(keyText) // your extracted internal methods : Sockeye.Biz.RavenKeyFactory.Sign(keyText); //test sign returns whole key with signature need to re-extract signature only actual = StripWs(Between(actual, "[SIGNATURE", "SIGNATURE]")); Assert.Equal(expected, actual); } [Fact] public void Fixture_covers_both_formats() { Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 1); Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 2); Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 3); } [Fact] public void Tampered_payload_does_not_match() { var row = ResignFixture.Rows.Values.First(r => r.Format == 1); var keyText = Between(row.Key, "[KEY", "KEY]") + "x"; var expected = StripWs(Between(row.Key, "[SIGNATURE", "SIGNATURE]")); Assert.NotEqual(expected, StripWs(Between(Sockeye.Biz.KeyFactory.Sign(keyText), "[SIGNATURE", "SIGNATURE]"))); } static string Between(string s, string start, string end) { int a = s.IndexOf(start, StringComparison.Ordinal); int b = s.IndexOf(end, StringComparison.Ordinal); if (a < 0 || b < 0 || b < a) throw new FormatException($"Markers {start}/{end} not found"); return s.Substring(a + start.Length, b - a - start.Length); } static string StripWs(string s) => string.Concat(s.Where(c => !char.IsWhiteSpace(c))); }