104 lines
4.7 KiB
Go
104 lines
4.7 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/os/gcfg"
|
|
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
|
|
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity"
|
|
)
|
|
|
|
func TestAppDiagnosisUpstreamContract(t *testing.T) {
|
|
scenarios := []string{"success", "session failure with IMEI", "IMEI failure with session"}
|
|
for _, scenario := range scenarios {
|
|
t.Run(scenario, func(t *testing.T) {
|
|
var mu sync.Mutex
|
|
seen := map[string]int{}
|
|
responses := map[string]string{
|
|
"sim-basic-info": `{"simStatus":"1","iccid":"card","imsi":"imsi","msisdn":"msisdn"}`,
|
|
"sim-status": `{"cardStatus":4}`,
|
|
"sim-session": `{"status":"0","apnId":"CMIOT","ipv4":"192.0.2.10"}`,
|
|
"sim-imei": `{"imei":"latest"}`,
|
|
"sim-device-status": `{"deviceStatus":"1","operatingStatus":"1"}`,
|
|
"sim-card-bind-status": `{"bindStatus":"1","orderStatus":"0"}`,
|
|
"sim-region-limit-status": `{"regionLimitStatus":"0","orderStatus":"1"}`,
|
|
"sim-data-diagnosis": `{"status":"0","message":"正确","result":[{"APNList":{"APNInfo":[{"APNName":"CMIOT","modifyTime":"20250526140211","APNStatus":"2","APNServiceUsageState":"1"}]}}]}`,
|
|
"sim-stop-reason": `{"stopReason":"000000000000"}`,
|
|
"sim-frozen-state": `{"frozenStatus":"0"}`,
|
|
"sim-datausage": `{"dataUsage":0}`,
|
|
"sim-apn-info": `{"apnList":[{"apnName":"CMIOT","status":"0"}]}`,
|
|
}
|
|
proxy := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
const prefix = "/internal/app-diagnosis/sim/query/"
|
|
if !strings.HasPrefix(request.URL.Path, prefix) || request.Header.Get("X-App-Diagnosis-Token") != "test-token" {
|
|
t.Errorf("proxy contract mismatch: %s", request.URL.Path)
|
|
}
|
|
var input appUpstreamSimQueryInput
|
|
if err := json.NewDecoder(request.Body).Decode(&input); err != nil || len(input.SimKeys) != 1 || input.SimKeys[0].ICCID != "card" || input.SimKeys[0].ChanKey != "test-channel" {
|
|
t.Errorf("query key mismatch: %+v, %v", input, err)
|
|
}
|
|
endpoint := strings.TrimPrefix(request.URL.Path, prefix)
|
|
mu.Lock()
|
|
seen[endpoint]++
|
|
mu.Unlock()
|
|
writer.Header().Set("Content-Type", "application/json")
|
|
fail := scenario == "session failure with IMEI" && endpoint == "sim-session" || scenario == "IMEI failure with session" && endpoint == "sim-imei"
|
|
if fail {
|
|
_, _ = writer.Write([]byte(`{"code":0,"data":[{"code":500,"message":"query failed"}]}`))
|
|
return
|
|
}
|
|
raw, ok := responses[endpoint]
|
|
if !ok {
|
|
t.Errorf("unknown endpoint: %s", endpoint)
|
|
return
|
|
}
|
|
_, _ = fmt.Fprintf(writer, `{"code":0,"data":[{"code":0,"resData":%s}]}`, raw)
|
|
}))
|
|
defer proxy.Close()
|
|
adapter, err := gcfg.NewAdapterContent(fmt.Sprintf(`{"upstream":{"default":{"clientName":%q,"timeout":"2s"},"appDiagnosisToken":"test-token","onelinkMock":{"enabled":true}}}`, proxy.URL))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
previous := g.Cfg().GetAdapter()
|
|
g.Cfg().SetAdapter(adapter)
|
|
t.Cleanup(func() { g.Cfg().SetAdapter(previous) })
|
|
row := &appCardQueryRow{TSimCardInfo: entity.TSimCardInfo{Id: 1, Iccid: "card", Imsi: "imsi", Msisdn: "msisdn", ChanKey: "test-channel", BossCardStatus: 2, DataServiceStatus: 1, Imei: "local-old"}}
|
|
result, err := NewAppDiagnosis().buildDiagnosisInfo(context.Background(), row, &model.AppCardModel{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.Info.Status == nil || *result.Info.Status != "4" {
|
|
t.Fatal("card status did not come from sim-status")
|
|
}
|
|
if result.Info.DataStatus == nil || *result.Info.DataStatus != "0" {
|
|
t.Fatal("APN status did not come from sim-apn-info")
|
|
}
|
|
if result.Info.UsedFlowMb == nil || *result.Info.UsedFlowMb != 0 {
|
|
t.Fatal("zero usage was lost")
|
|
}
|
|
if result.Info.RateLimitStatus == nil || *result.Info.RateLimitStatus != "1" || len(result.Info.RateLimitApnDetails) != 1 {
|
|
t.Fatal("mobile APN policy response was not normalized")
|
|
}
|
|
if scenario == "session failure with IMEI" {
|
|
if result.Modules["session"].Status != "error" || result.Info.OnlineStatus != nil || result.Session.Imei == nil || *result.Session.Imei != "latest" {
|
|
t.Fatal("session failure was masked or IMEI was not independent")
|
|
}
|
|
} else if scenario == "IMEI failure with session" {
|
|
if result.Modules["imei"].Status != "error" || result.Modules["session"].Status != "success" || result.Session.Imei != nil {
|
|
t.Fatal("IMEI failure fell back to another source")
|
|
}
|
|
} else if result.Info.OnlineStatus == nil || *result.Info.OnlineStatus != "1" {
|
|
t.Fatal("online status did not come from session")
|
|
}
|
|
})
|
|
}
|
|
}
|