using Xunit; namespace HikvisionAttendanceService.Tests; /// /// Covers delete-success parsing rules used by USER_DELETE confirmation /// (regex-based mirror so the test project does not need System.Web.Extensions). /// public class IsapiDeleteSuccessTests { [Theory] [InlineData("{\"statusCode\":1,\"statusString\":\"OK\",\"subStatusCode\":\"ok\"}", 200, true)] [InlineData("{\n \"statusCode\": 1,\n \"statusString\": \"OK\",\n \"subStatusCode\": \"ok\"\n}", 200, true)] [InlineData("{\"statusCode\":\"1\",\"statusString\":\"OK\",\"subStatusCode\":\"ok\"}", 200, true)] [InlineData("{ \"statusCode\" : 1 , \"statusString\" : \"OK\" }", 200, true)] [InlineData("{\"statusCode\":1,\"subStatusCode\":\"ok\"}", 200, true)] [InlineData("{\"statusCode\":1,\"statusString\":\"OK\"}", 200, true)] [InlineData("{\"statusCode\":1}", 200, false)] [InlineData("{\"statusCode\":4,\"statusString\":\"Invalid Operation\",\"subStatusCode\":\"employeeNoNotExist\"}", 200, false)] [InlineData("{\"statusCode\":1,\"statusString\":\"OK\",\"subStatusCode\":\"ok\"}", 400, false)] public void Confirmed_delete_success_rules(string body, int httpStatus, bool expected) { Assert.Equal(expected, IsConfirmed(body, httpStatus)); } [Fact] public void Failure_reason_maps_employee_not_found() { Assert.Equal( "Employee was not found on the device", Describe(200, 4, "Invalid Operation", "employeeNoNotExist")); } private static bool IsConfirmed(string? body, int httpStatus) { if (httpStatus < 200 || httpStatus >= 300) return false; if (!TryParse(body, out var statusCode, out var statusString, out var subStatusCode)) return false; if (statusCode != 1) return false; return string.Equals(statusString, "OK", System.StringComparison.OrdinalIgnoreCase) || string.Equals(subStatusCode, "ok", System.StringComparison.OrdinalIgnoreCase); } private static bool TryParse(string? body, out int statusCode, out string statusString, out string subStatusCode) { statusCode = 0; statusString = ""; subStatusCode = ""; if (string.IsNullOrWhiteSpace(body)) return false; var mCode = System.Text.RegularExpressions.Regex.Match(body, "\"statusCode\"\\s*:\\s*\"?(?-?\\d+)\"?", System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (mCode.Success) int.TryParse(mCode.Groups["v"].Value, out statusCode); var mStr = System.Text.RegularExpressions.Regex.Match(body, "\"statusString\"\\s*:\\s*\"(?[^\"]*)\"", System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (mStr.Success) statusString = mStr.Groups["v"].Value; var mSub = System.Text.RegularExpressions.Regex.Match(body, "\"subStatusCode\"\\s*:\\s*\"(?[^\"]*)\"", System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (mSub.Success) subStatusCode = mSub.Groups["v"].Value; return statusCode != 0 || statusString.Length > 0 || subStatusCode.Length > 0; } private static string Describe(int httpStatus, int statusCode, string statusString, string subStatusCode) { if (httpStatus < 200 || httpStatus >= 300) return "HTTP " + httpStatus; var sub = (subStatusCode ?? "").Trim(); if (sub.IndexOf("notExist", System.StringComparison.OrdinalIgnoreCase) >= 0 || sub.IndexOf("notFound", System.StringComparison.OrdinalIgnoreCase) >= 0 || sub.Equals("employeeNoNotExist", System.StringComparison.OrdinalIgnoreCase)) return "Employee was not found on the device"; if (!string.IsNullOrWhiteSpace(statusString) && !string.Equals(statusString, "OK", System.StringComparison.OrdinalIgnoreCase)) return statusString.Trim(); if (statusCode != 0 && statusCode != 1) return "Hikvision statusCode=" + statusCode; return "device delete rejected"; } }