Add unit tests for ISAPI delete success confirmation rules

Cover confirmed-success parsing for statusCode/OK/ok variants and concise failure mapping (e.g. employee not found).
main
SYED MUSTUFA AHMED NAQVI 2026-07-30 13:20:39 +05:00
parent 35ed884104
commit dec8513d86
1 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,89 @@
using Xunit;
namespace HikvisionAttendanceService.Tests;
/// <summary>
/// Covers delete-success parsing rules used by USER_DELETE confirmation
/// (regex-based mirror so the test project does not need System.Web.Extensions).
/// </summary>
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*\"?(?<v>-?\\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*\"(?<v>[^\"]*)\"",
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
if (mStr.Success) statusString = mStr.Groups["v"].Value;
var mSub = System.Text.RegularExpressions.Regex.Match(body,
"\"subStatusCode\"\\s*:\\s*\"(?<v>[^\"]*)\"",
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";
}
}