using System; using System.Text; namespace HanvonF710XAttendanceService { internal static class NedoTemplateConverterTests { private const string SampleJpegBase64 = "/9j/4AAQSkZJRgABAQEAOABkAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pLSwzOko+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0//wAARCACgAHgDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGfAP/Z"; public static int RunAll() { int failed = 0; failed += Run("1 detect NEDO XML", TestDetectNedoXml); failed += Run("2 extract valid NEDO photo", TestExtractValidNedoPhoto); failed += Run("3 missing NEDO photo", TestMissingNedoPhoto); failed += Run("4 invalid NEDO photo", TestInvalidNedoPhoto); failed += Run("5 NEDO plan uses face not record", TestNedoPlanUsesFace); failed += Run("6 Hanvon-native template uses record", TestHanvonNativeUsesRecord); failed += Run("7 NEDO plan uses profile verification", TestNedoUsesProfileVerification); failed += Run("8 employee 5 style NEDO blob", TestEmployee5StyleBlob); failed += Run("9 prepare upscales small NEDO photo", TestPrepareUpscalesSmallPhoto); return failed; } private static int Run(string name, Func test) { try { if (!test()) { Console.WriteLine("FAIL: " + name); return 1; } Console.WriteLine("PASS: " + name); return 0; } catch (Exception ex) { Console.WriteLine("FAIL: " + name + " err=" + ex.Message); return 1; } } private static bool TestDetectNedoXml() { string xml = BuildNedoXml("5", SampleJpegBase64); return NedoTemplateConverter.IsNedoXml(xml); } private static bool TestExtractValidNedoPhoto() { string xml = BuildNedoXml("5", SampleJpegBase64); NedoPhotoExtractResult result = NedoTemplateConverter.TryExtractPhoto(xml, out string photo); return result == NedoPhotoExtractResult.Found && photo == SampleJpegBase64 && NedoTemplateConverter.GetDecodedJpegByteLength(photo) > 0; } private static bool TestMissingNedoPhoto() { string xml = "id=\"5\" name=\"\" check_type=\"face\" face_data=\"abc\""; NedoPhotoExtractResult result = NedoTemplateConverter.TryExtractPhoto(xml, out string photo); return result == NedoPhotoExtractResult.Missing && photo == null; } private static bool TestInvalidNedoPhoto() { string xml = BuildNedoXml("5", "not-valid-base64!!!"); NedoPhotoExtractResult result = NedoTemplateConverter.TryExtractPhoto(xml, out string photo); return result == NedoPhotoExtractResult.Invalid && photo == null; } private static bool TestNedoPlanUsesFace() { string xml = BuildNedoXml("5", SampleJpegBase64); var plan = DbToDeviceUploadPlan.FromBlob(Encoding.UTF8.GetBytes(xml)); return plan.Format == DbToDeviceTemplateFormat.NedoXml && NedoTemplateConverter.UsesFaceField(plan) && !NedoTemplateConverter.UsesRecordField(plan); } private static bool TestHanvonNativeUsesRecord() { string record = Convert.ToBase64String(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); var plan = DbToDeviceUploadPlan.FromBlob(Encoding.UTF8.GetBytes(record)); return plan.Format == DbToDeviceTemplateFormat.HanvonRecord && NedoTemplateConverter.UsesRecordField(plan) && !NedoTemplateConverter.UsesFaceField(plan); } private static bool TestNedoUsesProfileVerification() { string xml = BuildNedoXml("5", SampleJpegBase64); var plan = DbToDeviceUploadPlan.FromBlob(Encoding.UTF8.GetBytes(xml)); return plan.UseProfileVerification; } private static bool TestEmployee5StyleBlob() { string xml = "id=\"5\" name=\"\" authority=\"0X11\" card_num=\"0Xffffffff\" calid=\"0\" check_type=\"face\" opendoor_type=\"face\" password=\"\" alg_edition=\"3.1\" sn=\"6753718120000147\"photo=\"" + SampleJpegBase64 + "\"face_data=\"abc\""; var plan = DbToDeviceUploadPlan.FromBlob(Encoding.UTF8.GetBytes(xml)); return plan.Format == DbToDeviceTemplateFormat.NedoXml && plan.HasUploadPayload && plan.NedoPhotoStatus == NedoPhotoExtractResult.Found; } private static bool TestPrepareUpscalesSmallPhoto() { var plan = DbToDeviceUploadPlan.FromBlob(Encoding.UTF8.GetBytes(BuildNedoXml("5", SampleJpegBase64))); if (!plan.TryPrepareFacePayload(out string error)) { return false; } return string.Equals(plan.PrepareNote, "upscaled", StringComparison.OrdinalIgnoreCase) && plan.PreparedWidth >= NedoPhotoPreprocessor.DefaultMinShortSide && plan.PreparedHeight >= NedoPhotoPreprocessor.DefaultMinShortSide; } private static string BuildNedoXml(string id, string photo) { return "id=\"" + id + "\" name=\"\" check_type=\"face\" photo=\"" + photo + "\" face_data=\"biometric-not-used\""; } } }