sync: 对齐小程序 v1.0.2 生产代码并脱敏
This commit is contained in:
@@ -8,6 +8,130 @@ import (
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
|
||||
)
|
||||
|
||||
func TestAppDiagnosisDataServiceStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
raw string
|
||||
want string
|
||||
}{
|
||||
{name: "disabled", raw: "0", want: "0"},
|
||||
{name: "enabled", raw: "1", want: "1"},
|
||||
{name: "unknown", raw: "2", want: "-1"},
|
||||
{name: "empty", raw: "", want: ""},
|
||||
{name: "invalid", raw: "unexpected", want: ""},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got := appDiagnosisDataServiceStatus(test.raw)
|
||||
if test.want == "" {
|
||||
if got != nil {
|
||||
t.Fatalf("appDiagnosisDataServiceStatus(%q) = %q, want nil", test.raw, *got)
|
||||
}
|
||||
return
|
||||
}
|
||||
if got == nil || *got != test.want {
|
||||
t.Fatalf("appDiagnosisDataServiceStatus(%q) = %v, want %q", test.raw, got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisDataServiceStatusFromApn(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
raw json.RawMessage
|
||||
want string
|
||||
}{
|
||||
{name: "mobile APN enabled", raw: json.RawMessage(`{"apnList":[{"apnName":"CMIOT","status":"1"}]}`), want: "1"},
|
||||
{name: "mobile APN disabled", raw: json.RawMessage(`{"apnList":[{"apnName":"CMIOT","status":"0"}]}`), want: "0"},
|
||||
{name: "ignore unrelated APN", raw: json.RawMessage(`{"apnList":[{"apnName":"OTHER","status":"0"},{"apnName":"cmiot","status":"1"}]}`), want: "1"},
|
||||
{name: "no APN entry", raw: json.RawMessage(`{"status":"1","apnList":[]}`)},
|
||||
{name: "other APN only", raw: json.RawMessage(`{"apnList":[{"apnName":"OTHER","status":"1"}]}`)},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got := appDiagnosisDataServiceStatusFromApn(test.raw)
|
||||
if test.want == "" {
|
||||
if got != nil {
|
||||
t.Fatalf("status = %q, want no data", *got)
|
||||
}
|
||||
return
|
||||
}
|
||||
if got == nil || *got != test.want {
|
||||
t.Fatalf("status = %v, want %q", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisDataServiceStatusFromItems(t *testing.T) {
|
||||
items := []appUpstreamSimQueryItem{
|
||||
{Code: 0, ResData: json.RawMessage(`{"apnList":[{"apnName":"OTHER","status":"0"}]}`)},
|
||||
{Code: 5000, ResData: json.RawMessage(`{"apnList":[{"apnName":"CMIOT","status":"0"}]}`)},
|
||||
{Code: 0, ResData: json.RawMessage(`{"apnList":[{"apnName":"CMIOT","status":"1"}]}`)},
|
||||
}
|
||||
status := appDiagnosisDataServiceStatusFromItems(items)
|
||||
if status == nil || *status != "1" {
|
||||
t.Fatalf("status = %v, want enabled CMIOT from successful upstream item", status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisDataServiceStatusForCarrier(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
tempKey string
|
||||
chanKey string
|
||||
raw json.RawMessage
|
||||
want string
|
||||
}{
|
||||
{name: "mobile only reads CMIOT", tempKey: "sim_yd_v5", raw: json.RawMessage(`{"apnList":[{"apnName":"OTHER","status":"1"}]}`)},
|
||||
{name: "telecom reads returned DNN", tempKey: "sim_dx_v1", raw: json.RawMessage(`{"apnList":[{"apnName":"ctnet","status":"1"}]}`), want: "1"},
|
||||
{name: "telecom reads disabled DNN", tempKey: "sim_dx_v1", raw: json.RawMessage(`{"apnList":[{"apnName":"ctnet","status":"0"}]}`), want: "0"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got := appDiagnosisDataServiceStatusFromItemsForChannel([]appUpstreamSimQueryItem{{Code: 0, ResData: test.raw}}, test.tempKey, test.chanKey)
|
||||
if test.want == "" {
|
||||
if got != nil {
|
||||
t.Fatalf("status = %q, want no data", *got)
|
||||
}
|
||||
return
|
||||
}
|
||||
if got == nil || *got != test.want {
|
||||
t.Fatalf("status = %v, want %q", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestAppDiagnosisAPNStatusRequiresAgreement(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
raw string
|
||||
want string
|
||||
}{
|
||||
{name: "all enabled", raw: `{"apnList":[{"apnName":"ctnet","status":"1"},{"apnName":"ctiot","status":"1"}]}`, want: "1"},
|
||||
{name: "all stopped", raw: `{"apnList":[{"apnName":"ctnet","status":"0"},{"apnName":"ctiot","status":"0"}]}`, want: "0"},
|
||||
{name: "mixed", raw: `{"apnList":[{"apnName":"ctnet","status":"1"},{"apnName":"ctiot","status":"0"}]}`},
|
||||
{name: "mixed reversed", raw: `{"apnList":[{"apnName":"ctiot","status":"0"},{"apnName":"ctnet","status":"1"}]}`},
|
||||
{name: "missing status", raw: `{"apnList":[{"apnName":"ctnet","status":"1"},{"apnName":"ctiot"}]}`},
|
||||
{name: "unknown status", raw: `{"apnList":[{"apnName":"ctnet","status":"1"},{"apnName":"ctiot","status":"-1"}]}`},
|
||||
{name: "missing name", raw: `{"apnList":[{"status":"1"}]}`},
|
||||
{name: "no mobile preference for telecom", raw: `{"apnList":[{"apnName":"CMIOT","status":"1"},{"apnName":"ctnet","status":"0"}]}`},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got := appDiagnosisDataServiceStatusFromItemsForChannel([]appUpstreamSimQueryItem{{Code: 0, ResData: json.RawMessage(test.raw)}}, "sim_dx_v1", "channel_dx")
|
||||
if test.want == "" {
|
||||
if got != nil {
|
||||
t.Fatalf("status = %q, want no data", *got)
|
||||
}
|
||||
} else if got == nil || *got != test.want {
|
||||
t.Fatalf("status = %v, want %q", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryDiagnosisFlowByCardRejectsUnsupportedPeriod(t *testing.T) {
|
||||
_, err := NewAppDiagnosis().queryDiagnosisFlowByCard(nil, nil, "12M")
|
||||
if err == nil || !strings.Contains(err.Error(), "3M") {
|
||||
@@ -15,6 +139,100 @@ func TestQueryDiagnosisFlowByCardRejectsUnsupportedPeriod(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDiagnosisCardChannelInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
info *appCardChannelInfo
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "missing channel", wantErr: true},
|
||||
{name: "empty channel key", info: &appCardChannelInfo{}, wantErr: true},
|
||||
{name: "disabled channel", info: &appCardChannelInfo{ChanKey: "channel-1", ChanStatus: 1}, wantErr: true},
|
||||
{name: "enabled channel", info: &appCardChannelInfo{ChanKey: "channel-1", ChanStatus: 0}},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := validateDiagnosisCardChannelInfo(test.info)
|
||||
if test.wantErr {
|
||||
if err == nil || !strings.Contains(err.Error(), appDiagnosisNotIncludedMessage) {
|
||||
t.Fatalf("error = %v, want %q", err, appDiagnosisNotIncludedMessage)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("error = %v, want nil", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisUnsupportedMessageIncludesUnsubscribedCapabilities(t *testing.T) {
|
||||
for _, message := range []string{"接口未订购", "能力未开通", "服务未开通", "未开通该接口", "通道未申请"} {
|
||||
if !appDiagnosisIsUnsupportedMessage(message) {
|
||||
t.Fatalf("message %q should be treated as unsupported", message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisModuleReason(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
status string
|
||||
message string
|
||||
want string
|
||||
}{
|
||||
{name: "unsubscribed", status: "skipped", message: "该卡未订购机卡绑定服务", want: "not_subscribed"},
|
||||
{name: "unsupported", status: "skipped", message: "运营商暂不支持", want: "unsupported"},
|
||||
{name: "empty skipped", status: "skipped", want: "unsupported"},
|
||||
{name: "no data", status: "skipped", message: "上游会话信息未返回有效结果", want: "no_data"},
|
||||
{name: "query error", status: "error", message: "查询超时", want: "query_error"},
|
||||
{name: "success", status: "success"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := appDiagnosisModuleReason(test.status, test.message); got != test.want {
|
||||
t.Fatalf("appDiagnosisModuleReason() = %q, want %q", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppSetDiagnosisModulePreservesStructuredReason(t *testing.T) {
|
||||
res := &model.AppDiagnosisInfoModel{}
|
||||
appSetDiagnosisModule(res, "cardBind", "skipped", "该卡未订购机卡绑定服务", false, "")
|
||||
module := res.Modules["cardBind"]
|
||||
if module == nil || module.Reason != "not_subscribed" || module.Message != "" {
|
||||
t.Fatalf("module = %+v, want hidden not_subscribed reason", module)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisDoesNotExposeUpstreamErrors(t *testing.T) {
|
||||
for _, message := range []string{"missing msisdn", "Missing MSISDN"} {
|
||||
res := &model.AppDiagnosisInfoModel{}
|
||||
status, displayMessage := appDiagnosisUpstreamFailure("上游机卡绑定状态查询失败", 9999, message)
|
||||
appSetDiagnosisModule(res, "cardBind", status, displayMessage, false, "")
|
||||
module := res.Modules["cardBind"]
|
||||
if module == nil || module.Status != "error" || module.Message != appDiagnosisRetryMessage {
|
||||
t.Fatalf("message %q: module = %+v", message, module)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisNormalizesLegacyBusyMessage(t *testing.T) {
|
||||
status, displayMessage := appDiagnosisUpstreamFailure("上游实时流量查询失败", 13000, "系统忙,请稍后再试")
|
||||
if status != "error" || displayMessage != appDiagnosisRetryMessage {
|
||||
t.Fatalf("status = %q, message = %q", status, displayMessage)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisHidesConnectivityFailureMessage(t *testing.T) {
|
||||
status, displayMessage := appDiagnosisUpstreamFailure("上游实时流量查询失败", 9999, "dial tcp 127.0.0.1:8510: connection refused")
|
||||
if status != "error" || displayMessage != "" {
|
||||
t.Fatalf("status = %q, message = %q", status, displayMessage)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppCachedDiagnosisRegionModuleTreatsCachedDataAsSuccess(t *testing.T) {
|
||||
raw, err := json.Marshal(map[string]string{
|
||||
"regionLimitStatus": "1",
|
||||
@@ -103,7 +321,7 @@ func TestAppDiagnosisApplyRateLimitIncludesApnDetails(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeOpenDiagnosisInfoMasksIdentifiersAndRemovesNetworkData(t *testing.T) {
|
||||
func TestSanitizeOpenDiagnosisInfoKeepsImeiAndRemovesOtherNetworkData(t *testing.T) {
|
||||
res := &model.AppDiagnosisInfoModel{
|
||||
Info: &model.AppDiagnosisInfoItem{
|
||||
Iccid: appDiagnosisStringPtr("8986001234567890123"),
|
||||
@@ -116,7 +334,7 @@ func TestSanitizeOpenDiagnosisInfoMasksIdentifiersAndRemovesNetworkData(t *testi
|
||||
Session: &model.AppDiagnosisSessionItem{
|
||||
ApnId: appDiagnosisStringPtr("internet"),
|
||||
Imei: appDiagnosisStringPtr("860123456789012"),
|
||||
Ipv4: appDiagnosisStringPtr("10.0.0.1"),
|
||||
Ipv4: appDiagnosisStringPtr("192.0.2.10"),
|
||||
Ipv6: appDiagnosisStringPtr("2001:db8::1"),
|
||||
},
|
||||
Card: &model.AppCardModel{
|
||||
@@ -124,7 +342,7 @@ func TestSanitizeOpenDiagnosisInfoMasksIdentifiersAndRemovesNetworkData(t *testi
|
||||
Msisdn: "13800008000",
|
||||
Imsi: "460001234567890",
|
||||
Imei: "860123456789012",
|
||||
Ipv4: "10.0.0.1",
|
||||
Ipv4: "192.0.2.10",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -135,24 +353,30 @@ func TestSanitizeOpenDiagnosisInfoMasksIdentifiersAndRemovesNetworkData(t *testi
|
||||
if got := *res.Info.Msisdn; got != "1380****8000" {
|
||||
t.Fatalf("masked MSISDN = %q", got)
|
||||
}
|
||||
if res.Info.Imsi != nil || len(res.Info.RateLimitApnDetails) != 0 || res.Session.ApnId != nil || res.Session.Imei != nil || res.Session.Ipv4 != nil {
|
||||
if res.Info.Imsi != nil || len(res.Info.RateLimitApnDetails) != 0 || res.Session.ApnId != nil || res.Session.Ipv4 != nil {
|
||||
t.Fatal("sensitive diagnosis fields were not removed")
|
||||
}
|
||||
if res.Card.Imsi != "" || res.Card.Imei != "" || res.Card.Ipv4 != "" {
|
||||
if res.Session.Imei == nil || *res.Session.Imei != "860123456789012" {
|
||||
t.Fatalf("session IMEI = %#v, want public 30-day IMEI", res.Session.Imei)
|
||||
}
|
||||
if res.Card.Imsi != "" || res.Card.Imei != "860123456789012" || res.Card.Ipv4 != "" {
|
||||
t.Fatal("sensitive card fields were not removed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDiagnosisInfoKeepsSessionImeiBeforeOpenSanitization(t *testing.T) {
|
||||
res := &model.AppDiagnosisInfoModel{
|
||||
Session: &model.AppDiagnosisSessionItem{Imei: appDiagnosisStringPtr("860123456789012")},
|
||||
func TestAppDiagnosisLatestImeiUsesSuccessfulGatewayResult(t *testing.T) {
|
||||
raw, err := json.Marshal(map[string]any{
|
||||
"resData": map[string]string{"imei": "861789024851199"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("marshal IMEI response: %v", err)
|
||||
}
|
||||
if res.Session.Imei == nil || *res.Session.Imei != "860123456789012" {
|
||||
t.Fatal("authenticated diagnosis should keep session IMEI")
|
||||
items := []appUpstreamSimQueryItem{
|
||||
{Code: 5000, ResData: json.RawMessage(`{"imei":"ignored"}`)},
|
||||
{Code: 0, ResData: raw},
|
||||
}
|
||||
sanitizeOpenDiagnosisInfo(res)
|
||||
if res.Session.Imei != nil {
|
||||
t.Fatal("open diagnosis should remove session IMEI")
|
||||
if got := appDiagnosisLatestImei(items); got != "861789024851199" {
|
||||
t.Fatalf("latest IMEI = %q, want 861789024851199", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +430,30 @@ func TestAppDiagnosisBindStatusSupportsTelecomCardBindingType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisShouldCacheRegionLimitMatchesConsoleChannels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
tempKey string
|
||||
chanKey string
|
||||
want bool
|
||||
}{
|
||||
{name: "mobile template", tempKey: "sim_yd", want: true},
|
||||
{name: "mobile mock channel", chanKey: "channel_yd_mock", want: true},
|
||||
{name: "onelink", chanKey: "onelink_shared", want: true},
|
||||
{name: "shared token", tempKey: "shared_token", want: true},
|
||||
{name: "telecom", tempKey: "sim_dx", chanKey: "channel_dx", want: false},
|
||||
{name: "unicom", tempKey: "sim_lt", chanKey: "channel_lt", want: false},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := appDiagnosisShouldCacheRegionLimit(test.tempKey, test.chanKey); got != test.want {
|
||||
t.Fatalf("appDiagnosisShouldCacheRegionLimit(%q, %q) = %v, want %v", test.tempKey, test.chanKey, got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppDiagnosisSessionStatusNormalizesUpstreamValues(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
"0": "0",
|
||||
|
||||
Reference in New Issue
Block a user