Files
tyapi-server/internal/domains/api/services/processors/dwbg/dwbg6a2c_test.go
2026-07-08 21:56:39 +08:00

448 lines
13 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dwbg
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
"tyapi-server/internal/domains/api/dto"
"go.uber.org/zap"
)
func TestEmptySinanReportMarshal(t *testing.T) {
params := dto.DWBG6A2CReq{
Name: "张三",
IDCard: "320321199102011152",
MobileNo: "13812345678",
}
report := emptySinanReport(params)
data, err := json.Marshal(report)
if err != nil {
t.Fatalf("序列化失败: %v", err)
}
var parsed map[string]interface{}
if err := json.Unmarshal(data, &parsed); err != nil {
t.Fatalf("反序列化失败: %v", err)
}
requiredModules := []string{
"baseInfo", "standLiveInfo", "riskPoint", "securityInfo", "antiFraudInfo",
"riskList", "applicationStatistics", "lendingStatistics", "performanceStatistics",
"overdueRecord", "creditDetail", "rentalBehavior", "riskSupervision", "judicialLeaseReport",
}
for _, module := range requiredModules {
if _, ok := parsed[module]; !ok {
t.Errorf("缺少顶层模块: %s", module)
}
}
antiFraud, ok := parsed["antiFraudInfo"].(map[string]interface{})
if !ok {
t.Fatal("antiFraudInfo 类型错误")
}
for _, key := range []string{"moneyLaundering", "deceiver", "gamblerPlayer", "gamblerBanker"} {
if _, exists := antiFraud[key]; !exists {
t.Errorf("antiFraudInfo 缺少键: %s", key)
}
}
rental, ok := parsed["rentalBehavior"].(map[string]interface{})
if !ok {
t.Fatal("rentalBehavior 类型错误")
}
if len(rental) != len(rentalBehaviorFieldNames) {
t.Errorf("rentalBehavior 字段数 = %d, want %d", len(rental), len(rentalBehaviorFieldNames))
}
}
func TestTransformToSinanReportAllNil(t *testing.T) {
params := dto.DWBG6A2CReq{
Name: "张三",
IDCard: "320321199102011152",
MobileNo: "13812345678",
}
apiData := map[string]interface{}{
"YYSY35TA": nil,
"YYSYE7V5": nil,
"YYSYH6F3": nil,
"YYSYP0T4": nil,
"FLXGDEA9": nil,
"FLXG8B4D": nil,
"FLXG7E8F": nil,
"JRZQ5E9F": nil,
"JRZQ1D09": nil,
}
report := transformToSinanReport(apiData, params, zap.NewNop())
if _, err := json.Marshal(report); err != nil {
t.Fatalf("全 nil 数据源仍应可序列化: %v", err)
}
}
func TestTransformToSinanReportWithMockData(t *testing.T) {
params := dto.DWBG6A2CReq{
Name: "黄春丽",
IDCard: "452621197903185522",
MobileNo: "13907764404",
}
apiData := map[string]interface{}{
"YYSYH6F3": map[string]interface{}{
"result": "0",
"sex": "女",
"address": "广西壮族自治区百色地区百色市",
"channel": "cmcc",
},
"YYSYE7V5": map[string]interface{}{
"status": 0,
"channel": "cmcc",
},
"YYSY35TA": map[string]interface{}{
"prov": "广西壮族自治区",
"city": "南宁",
"name": "中国移动",
},
"YYSYP0T4": map[string]interface{}{
"time": "[24,-1)",
},
"FLXG8B4D": map[string]interface{}{
"gamblerBanker": "A",
},
"FLXGDEA9": map[string]interface{}{
"level": "A1,C3",
},
"JRZQ5E9F": map[string]interface{}{
"xyp_cpl0001": "2",
"xyp_cpl0007": "2",
"xyp_cpl0008": "1",
"xyp_cpl0011": "2",
"xyp_cpl0012": "2",
"xyp_cpl0013": "3",
"xyp_cpl0044": "1",
"xyp_cpl0074": "0.56",
"xyp_model_score_mid": "500",
},
"JRZQ1D09": map[string]interface{}{
"m12": map[string]interface{}{
"id": map[string]interface{}{"allnum": "7", "orgnum": "1", "tot_mons": "16"},
"cell": map[string]interface{}{"allnum": "7", "orgnum": "1", "tot_mons": "16"},
},
"idcard_relation_phone": 1,
"phone_relation_idard": 0,
},
}
report := transformToSinanReport(apiData, params, zap.NewNop())
standLive := report["standLiveInfo"].(map[string]interface{})
if standLive["finalAuthResult"] != "0" || standLive["verification"] != "0" {
t.Errorf("standLiveInfo 三要素映射错误: %+v", standLive)
}
if standLive["inTime"] != "24" {
t.Errorf("inTime = %v, want 24", standLive["inTime"])
}
security := report["securityInfo"].(map[string]interface{})
if security["front"] != 1 || security["escape"] != 0 || security["drug"] != 1 {
t.Errorf("securityInfo 解析错误: %+v", security)
}
antiFraud := report["antiFraudInfo"].(map[string]interface{})
if antiFraud["gamblerBanker"] != "A" {
t.Errorf("antiFraudInfo.gamblerBanker = %v", antiFraud["gamblerBanker"])
}
riskList := report["riskList"].(map[string]interface{})
if riskList["creditLeaseRisk"] != 1 {
t.Errorf("creditLeaseRisk = %v, want 1", riskList["creditLeaseRisk"])
}
if riskList["vehicleLeaseViolation"] != 1 {
t.Errorf("vehicleLeaseViolation = %v, want 1", riskList["vehicleLeaseViolation"])
}
if riskList["highRiskArea"] != 0 {
t.Errorf("highRiskArea = %v, want 0", riskList["highRiskArea"])
}
riskPoint := report["riskPoint"].(map[string]interface{})
if riskPoint["antiFraudRisk"] != 1 {
t.Errorf("antiFraudRisk = %v, want 1", riskPoint["antiFraudRisk"])
}
if riskPoint["judicialCase"] != 0 {
t.Errorf("judicialCase = %v, want 0", riskPoint["judicialCase"])
}
perf := report["performanceStatistics"].(map[string]interface{})
if perf["serialVersionUID"] != 1 {
t.Errorf("serialVersionUID = %v, want 1", perf["serialVersionUID"])
}
}
func TestMapYYSYH6F3StandLive(t *testing.T) {
cases := []struct {
result, wantFinal, wantVerify string
}{
{"0", "0", "0"},
{"1", "1", "1"},
{"2", "1", "-1"},
{"", "1", "-1"},
}
for _, tc := range cases {
final, verify := mapYYSYH6F3StandLive(tc.result)
if final != tc.wantFinal || verify != tc.wantVerify {
t.Errorf("result=%q got (%s,%s) want (%s,%s)", tc.result, final, verify, tc.wantFinal, tc.wantVerify)
}
}
}
func TestParseSecurityInfoLevel(t *testing.T) {
info := parseSecurityInfoLevel("A,C3")
if info["escape"] != 1 || info["front"] != 0 || info["drug"] != 1 {
t.Fatalf("A,C3 => %+v", info)
}
info = parseSecurityInfoLevel("A1")
if info["front"] != 1 || info["escape"] != 0 {
t.Fatalf("A1 => %+v", info)
}
}
func TestIndustryBlacklistHit(t *testing.T) {
if !industryBlacklistHit("D1,B") {
t.Fatal("D1 should hit industry blacklist")
}
if industryBlacklistHit("A1,C3") {
t.Fatal("A1,C3 should not hit industry blacklist")
}
}
func TestReportNoNullValues(t *testing.T) {
params := dto.DWBG6A2CReq{
Name: "张三",
IDCard: "320321199102011152",
MobileNo: "13812345678",
}
apiData := map[string]interface{}{
"FLXG7E8F": map[string]interface{}{
"judicial_data": map[string]interface{}{
"breachCaseList": []interface{}{},
"consumptionRestrictionList": []interface{}{},
"lawsuitStat": map[string]interface{}{
"count": map[string]interface{}{
"count_beigao": 0,
"larq_stat": "",
},
"civil": map[string]interface{}{
"cases": []interface{}{},
"count": map[string]interface{}{"count_total": 0},
},
},
},
},
}
report := transformToSinanReport(apiData, params, zap.NewNop())
cleaned, ok := stripNullValues(report).(map[string]interface{})
if !ok {
t.Fatal("stripNullValues failed")
}
if reportContainsNull(cleaned) {
t.Fatal("report still contains null after strip")
}
data, err := json.Marshal(cleaned)
if err != nil {
t.Fatalf("marshal failed: %v", err)
}
if strings.Contains(string(data), "null") {
t.Fatalf("JSON contains null: %s", string(data))
}
}
func TestBuildJudicialLeaseReportWithCases(t *testing.T) {
apiData := map[string]interface{}{
"FLXG7E8F": map[string]interface{}{
"judicial_data": map[string]interface{}{
"breachCaseList": []interface{}{},
"consumptionRestrictionList": []interface{}{},
"lawsuitStat": map[string]interface{}{
"count": map[string]interface{}{
"count_total": 1,
"count_beigao": 1,
"larq_stat": "2026(1)",
"ay_stat": "民事(1)",
},
"civil": map[string]interface{}{
"cases": []interface{}{
map[string]interface{}{
"c_ah": "2019桂0103民初5129号",
"n_ssdw": "原告",
"n_ajjzjd": "已结案",
"n_ajlx": "民事一审",
"c_dsrxx": []interface{}{
map[string]interface{}{
"c_mc": "黄春丽",
"n_ssdw": "原告",
"n_dsrlx": "自然人",
},
},
},
},
"count": map[string]interface{}{
"count_total": 1,
"count_beigao": 1,
},
},
"preservation": map[string]interface{}{
"cases": []interface{}{},
"count": map[string]interface{}{"count_total": 1},
},
"implement": map[string]interface{}{
"cases": []interface{}{},
"count": map[string]interface{}{"count_total": 0},
},
},
},
},
}
jlr := buildJudicialLeaseReport(apiData)
courtInfo := jlr["courtInfo"].(map[string]interface{})
if courtInfo["civilCasesCount"] != 1 {
t.Fatalf("civilCasesCount = %v", courtInfo["civilCasesCount"])
}
if courtInfo["preservationCasesCount"] != 1 {
t.Fatalf("preservationCasesCount = %v", courtInfo["preservationCasesCount"])
}
newMult := courtInfo["newMultCourtInfo"].(map[string]interface{})
civilCases, ok := newMult["civilCases"].([]interface{})
if !ok || len(civilCases) != 1 {
t.Fatalf("civilCases missing or empty: %+v", newMult["civilCases"])
}
if _, has := newMult["preservationCases"]; has {
t.Fatal("preservationCases list should be omitted when empty")
}
overview := jlr["caseOverviewInfo"].(map[string]interface{})
if overview["beigaoTotalCasesCounts"] != 1 {
t.Fatalf("beigaoTotalCasesCounts = %v", overview["beigaoTotalCasesCounts"])
}
}
func TestT2SampleJudicialAndSecurityMapping(t *testing.T) {
base := filepath.Join("..", "..", "..", "..", "..", "..", "..", "司南报告")
load := func(name string) map[string]interface{} {
b, err := os.ReadFile(filepath.Join(base, name))
if err != nil {
t.Fatalf("read %s: %v", name, err)
}
var m map[string]interface{}
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal %s: %v", name, err)
}
return m
}
params := dto.DWBG6A2CReq{
Name: "何志勇",
IDCard: "45212719910201152X",
MobileNo: "18277111590",
}
apiData := map[string]interface{}{
"FLXG7E8F": load("t2-1.json"),
"FLXGDEA9": load("t2-2.json"),
}
report := transformToSinanReport(apiData, params, zap.NewNop())
jlr := report["judicialLeaseReport"].(map[string]interface{})
courtInfo := jlr["courtInfo"].(map[string]interface{})
if courtInfo["criminalCasesCount"] != 4 {
t.Fatalf("criminalCasesCount = %v, want 4", courtInfo["criminalCasesCount"])
}
newMult := courtInfo["newMultCourtInfo"].(map[string]interface{})
criminalCases, ok := newMult["criminalCases"].([]interface{})
if !ok || len(criminalCases) != 4 {
t.Fatalf("criminalCases = %v, want 4 items", newMult["criminalCases"])
}
overview := jlr["caseOverviewInfo"].(map[string]interface{})
if overview["beigaoTotalCasesCounts"] != 2 {
t.Fatalf("beigaoTotalCasesCounts = %v, want 2", overview["beigaoTotalCasesCounts"])
}
if overview["leastCaseTime"] != "2019(2)" {
t.Fatalf("leastCaseTime = %v, want 2019(2)", overview["leastCaseTime"])
}
security := report["securityInfo"].(map[string]interface{})
if security["escape"] != 1 || security["icase"] != 1 {
t.Fatalf("securityInfo A => %+v", security)
}
if security["ikey"] != 1 {
t.Fatalf("securityInfo D5 => ikey=%v", security["ikey"])
}
riskPoint := report["riskPoint"].(map[string]interface{})
if riskPoint["judicialRisk"] != 1 || riskPoint["legalCasesFlag"] != 1 {
t.Fatalf("riskPoint judicial flags = %+v", riskPoint)
}
if riskPoint["securityRisk"] != 1 {
t.Fatalf("securityRisk = %v, want 1", riskPoint["securityRisk"])
}
}
func TestT2SampleWithDataWrapper(t *testing.T) {
base := filepath.Join("..", "..", "..", "..", "..", "..", "..", "司南报告")
load := func(name string) map[string]interface{} {
b, err := os.ReadFile(filepath.Join(base, name))
if err != nil {
t.Fatalf("read %s: %v", name, err)
}
var m map[string]interface{}
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal %s: %v", name, err)
}
return m
}
params := dto.DWBG6A2CReq{
Name: "何志勇",
IDCard: "45212719910201152X",
MobileNo: "18277111590",
}
apiData := map[string]interface{}{
"FLXG7E8F": map[string]interface{}{"data": load("t2-1.json")},
"FLXGDEA9": map[string]interface{}{"data": load("t2-2.json")},
}
report := transformToSinanReport(apiData, params, zap.NewNop())
jlr := report["judicialLeaseReport"].(map[string]interface{})
courtInfo := jlr["courtInfo"].(map[string]interface{})
if courtInfo["criminalCasesCount"] != 4 {
t.Fatalf("wrapped criminalCasesCount = %v, want 4", courtInfo["criminalCasesCount"])
}
security := report["securityInfo"].(map[string]interface{})
if security["escape"] != 1 || security["ikey"] != 1 {
t.Fatalf("wrapped securityInfo = %+v", security)
}
riskList := report["riskList"].(map[string]interface{})
if riskList["industryBlacklist"] != 1 {
t.Fatalf("wrapped industryBlacklist = %v, want 1", riskList["industryBlacklist"])
}
}
func TestM1PlusCountCaps(t *testing.T) {
apiData := map[string]interface{}{
"JRZQ5E9F": map[string]interface{}{
"xyp_cpl0029": "1",
"xyp_cpl0030": "1",
"xyp_cpl0031": "1",
},
}
record := buildOverdueRecord(apiData)
if record["m1PlusCountLast6Months"] != 3 {
t.Fatalf("6m cap = %v", record["m1PlusCountLast6Months"])
}
if record["m1PlusCountLast12Months"] != 3 {
t.Fatalf("12m cap = %v", record["m1PlusCountLast12Months"])
}
}