package test import ( "encoding/json" "errors" "fmt" "math" "path/filepath" "regexp" "runtime" "strconv" "strings" "sws_xcx/enums" "sws_xcx/models" _ "sws_xcx/routers" "sws_xcx/service" "sws_xcx/utils" "testing" "time" "unicode/utf8" //beego "github.com/beego/beego/v2/server/web" //"github.com/beego/beego/v2/core/logs" "github.com/astaxie/beego" "github.com/jinzhu/gorm" "github.com/medivhzhan/weapp/v3/auth" // "github.com/smartystreets/goconvey/convey" ) func init() { _, file, _, _ := runtime.Caller(0) apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator)))) beego.TestBeegoInit(apppath) } // TestGet is a sample to run an endpoint test func TestGet(t *testing.T) { // r, _ := http.NewRequest("GET", "/v1/object", nil) // w := httptest.NewRecorder() // beego.BeeApp.Handlers.ServeHTTP(w, r) // logs.Info("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String()) // Convey("Subject: Test Station Endpoint\n", t, func() { // Convey("Status Code Should Be 200", func() { // So(w.Code, ShouldEqual, 200) // }) // Convey("The Result Should Not Be Empty", func() { // So(w.Body.Len(), ShouldBeGreaterThan, 0) // }) // }) t.Log("TestGet") } func TestWxappSessionCode(t *testing.T) { sdk := service.GetWxSdk() wxcli := sdk.NewAuth() code := "0d3eVp100qtUES1jgD300t5yN21eVp1t" resp, err := wxcli.Code2Session(&auth.Code2SessionRequest{JsCode: code, GrantType: "authorization_code", Appid: beego.AppConfig.String("appid"), Secret: beego.AppConfig.String("appsecret")}) if err != nil { t.Error(err) return } if resp.CommonError.ErrCode != 0 { t.Errorf("err code:%v msg:%v", resp.CommonError.ErrCode, resp.CommonError.ErrMSG) return } t.Logf("resp: %+v", *resp) } func TestJson(t *testing.T) { req := `{"id":1,"nick_name":"zhangsan","ctime":"2019-11-20 16:49:08"}` u := models.UserInfoResp{} err := json.Unmarshal([]byte(req), &u) if err != nil { t.Error(err) } t.Logf("u:%+v", u) } func TestHandleMsg(t *testing.T) { req := []byte(`{"publish_received_at":1722839054218,"pub_props":{"User-Property":{}},"peerhost":"124.133.43.122","qos":0,"topic":"/CH-U100/09012201100010104/user/checkresult","clientid":"42915152F3F1","payload":"{\"productKey\":\"CH-U100\",\"deviceName\":\"09012201100010104\",\"acc\":12378,\"type\":0,\"count\":14,\"datatype\":0,\"verifycode\":212,\"data\":\"0,0,0,2,2,0,0,0,0,0,4,3,0,1\",\"origin\":\"4243305A0000010E0000000202000000000004030001D4\",\"len\":23}","username":"09012201100010104","event":"message.publish","metadata":{"rule_id":"checkresult"},"timestamp":1722839054218,"node":"emqx@127.0.0.1","id":"00061EE9B9D4F6AFF445000924860003","flags":{"retain":false,"dup":false}}`) msg := &models.OpenEmqMsgReqVO{} err := json.Unmarshal(req, msg) if err != nil { t.Error(err) return } ds := service.NewDeviceService() device, err := ds.GetDeviceByNo(msg.UserName) if err != nil && err != gorm.ErrRecordNotFound { utils.ErrorLog("GetDeviceByNo %v:", err) t.Error(err) return } if device.Id == 0 { utils.WarningLog("非本系统设备,数据废弃") return } err = ds.CreateDeviceMessageLog(models.DeviceMessageLog{ DeviceName: msg.DeviceName, Content: string(req), EventType: enums.EventTypeEmqx, MessageId: msg.Id, Topic: msg.Topic, }) if err != nil { utils.ErrorLog("CreateDeviceMessageLog %v:", err) t.Error(err) return } payload := &models.OpenEmqPayloadReqVO{} err = json.Unmarshal([]byte(msg.Payload), payload) if err != nil { utils.ErrorLog("json.Unmarshal %v:", err) t.Error(err) return } if payload.Len != 23 { utils.WarningLog("非标准数据,数据废弃:%v", msg.Payload) } dr, err := ds.GetDeviceRelateByDeviceId(device.Id) if err != nil { utils.ErrorLog("GetDeviceRelateByDeviceId %v:", err) t.Error(err) return } checkRecord := &models.CheckRecord{ Acc: payload.Acc, PutSources: enums.EventTypeEmqx, MessageId: msg.Id, DeviceId: device.Id, UserId: dr.UserId, DeviceStatus: device.Status, } if dr.UserId > 0 { hp, err := service.NewUserHealthProfileService().GetUserHealthProfileByUserId(dr.UserId) if err != nil { utils.ErrorLog("GetUserHealthProfileByUserId %v:", err) t.Error(err) return } checkRecord.UserHealthProfileId = int64(hp.Id) } crs := service.NewCheckRecordService() err = crs.CreateCheckRecord(checkRecord) if err != nil { utils.ErrorLog("CreateCheckRecord %v:", err) t.Error(err) return } t.Log(checkRecord.Id) t.Log(payload.Data) da := strings.Split(payload.Data, ",") count := payload.Count if len(da) != count { t.Logf("数据长度不匹配,截取存储 %+v", payload) if len(da) < count { count = len(da) } } checkItems, err := service.NewCheckItemService().GetCheckItems("cn", device.DeviceType) if err != nil { utils.ErrorLog("GetCheckItems %v:", err) t.Error(err) return } if len(checkItems) < count { t.Error("接收的数据于检查项目配置不一致") return } alerts := make([]string, 0) for i := 0; i < count; i++ { vi, _ := strconv.Atoi(da[i]) err = createCheckRecordItem(checkItems, checkRecord.Id, &alerts, vi, i+1, crs) if err != nil { utils.ErrorLog("createCheckRecordItem valule:%v, err:%v:", vi, err) } } if len(alerts) > 0 { alertItemIds := strings.Join(alerts, ",") err = crs.UpdateCheckRecordAlertItems(checkRecord.Id, alertItemIds) if err != nil { utils.ErrorLog("UpdateCheckRecordAlertItems %v:", err) t.Error(err) return } } else { utils.TraceLog("无异常数据") } } var DIGITS = []rune{ 'S', 'V', 'X', '5', '0', '8', '-', 'N', 'i', 'm', 'd', 'u', 'H', 'O', 'Q', 'E', 'D', 'v', 't', '2', 'c', 'p', '1', '3', 'z', 'R', 'a', 'W', 'l', 'G', 'k', 'A', '9', 'o', 's', 'g', 'y', '4', 'w', 'L', 'T', 'Y', 'b', '+', 'J', 'x', '7', 'r', 'I', 'n', 'f', 'Z', 'e', 'M', 'C', 'P', 'U', 'B', 'j', '6', 'F', 'K', 'h', 'q', } func TestHandleQrCode(t *testing.T) { result := "http://d.j6c.cn/E0YUQ|XGU|5Vy.z6k&EZf" //result = "E0YUQ|XGU|5Vy.z6k&EZf" var userId uint64 if result != "" { re := regexp.MustCompile(`(http.*/)?(.+)$`) matches := re.FindStringSubmatch(result) str := matches[2] parity := str[len(str)-1:] st := int8(0) result1 := result[:len(result)-1] for i := 0; i < utf8.RuneCountInString(result1); i++ { r, _ := utf8.DecodeRuneInString(result1[i:]) st += int8(r) st = int8(getUint8(int(st))) } digit := DIGITS[getUint8(int(^st))%64] if string(digit) != parity { t.Error("检测数据校验不通过") return } item, err := strconv.ParseInt(str[:1], 16, 32) if err != nil { t.Error(err) return } if item != 14 && item != 11 { t.Error("无法解析检测结果") return } strs := str[1 : len(str)-1] strs = regexp.MustCompile(`[._&$|]`).ReplaceAllString(strs, " ") strsArray := strings.Fields(strs) if len(strsArray) < 5 { t.Error("无法解析检测结果") return } serialno := "09" + formatNumber(radixString(strsArray[0]), 8) serialno += formatNumber(radixString(strsArray[1]), 7) acc := int(radixString(strsArray[2])) checkResultStr := formatNumber(radixString(strsArray[3]), 7) if item == 14 { checkResultStr += formatNumber(radixString(strsArray[4]), 7) } else if item == 11 { checkResultStr += formatNumber(radixString(strsArray[4]), 4) } fmt.Println("Device Name:", serialno) fmt.Println("Acc:", acc) fmt.Println("Check Result String:", checkResultStr) device, err := service.NewDeviceService().GetDeviceByNo(serialno) if err != nil { t.Error(err) return } if device.Id == 0 { t.Error("不是本系统中的设备,无法解析结果") return } ds := service.NewDeviceService() dr, err := ds.GetDeviceRelateByDeviceId(device.Id) if err != nil { t.Error(err) return } var status int if dr.Id == 0 { //设备未绑定 提示绑定 status = 1 } else if dr.UserId != userId { //别人已经绑定设备,返回结果 并提示 status = 2 } else { //自己绑定的设备,返回结果不提示 status = 3 } da := strings.Split(checkResultStr, "") count := len(da) checkItems, err := service.NewCheckItemService().GetCheckItems("cn", device.DeviceType) if err != nil { utils.ErrorLog("GetCheckItems %v:", err) t.Error(err) return } crs := service.NewCheckRecordService() record, err := crs.GetCheckRecordByAcc(device.Id, acc) if err != nil { utils.ErrorLog("GetCheckRecordByAcc %v:", err) t.Error(err) } if record.Id == 0 { //创建记录 err = ds.CreateDeviceMessageLog(models.DeviceMessageLog{ DeviceName: device.DeviceName, Content: result, EventType: enums.EventTypeQrCode, }) if err != nil { utils.ErrorLog("CreateDeviceMessageLog %v:", err) t.Error(err) return } if len(checkItems) < count { t.Error("接收的数据与检查项目配置不一致") return } checkRecord := &models.CheckRecord{ Acc: acc, PutSources: enums.EventTypeQrCode, DeviceId: device.Id, UserId: dr.UserId, DeviceStatus: device.Status, Ctime: time.Now(), } if dr.UserId > 0 { hp, err := service.NewUserHealthProfileService().GetUserHealthProfileByUserId(dr.UserId) if err != nil { utils.ErrorLog("GetUserHealthProfileByUserId %v:", err) t.Error(err) return } checkRecord.UserHealthProfileId = int64(hp.Id) } err = crs.CreateCheckRecord(checkRecord) if err != nil { utils.ErrorLog("CreateCheckRecord %v:", err) t.Error(err) return } alerts := make([]string, 0) for i := 0; i < count; i++ { vi, _ := strconv.Atoi(da[i]) err = createCheckRecordItem(checkItems, checkRecord.Id, &alerts, vi, i+1, crs) if err != nil { utils.ErrorLog("createCheckRecordItem valule:%v, err:%v:", vi, err) } } if len(alerts) > 0 { alertItemIds := strings.Join(alerts, ",") err = crs.UpdateCheckRecordAlertItems(checkRecord.Id, alertItemIds) if err != nil { utils.ErrorLog("UpdateCheckRecordAlertItems %v:", err) t.Error(err) return } } else { utils.TraceLog("无异常数据") } record = *checkRecord } recordItems, err := crs.GetCheckRecordItems(record.Id) if err != nil { utils.ErrorLog("GetCheckRecordItems %v:", err) t.Error(err) return } checkRecordItem, err := analyzeCheckRecord(recordItems, checkItems) if err != nil { t.Error(err) return } checkRecordItem.Status = status checkRecordItem.CheckDate = record.Ctime checkRecordItem.UserID = int64(record.UserId) checkRecordItem.Bind = checkRecordItem.UserID > 0 checkRecordItem.CheckRecordID = record.Id t.Logf("result:%+v", checkRecordItem) } } func analyzeCheckRecord(ritems []*models.CheckRecordItem, citems []*models.CheckItem) (models.AppCheckRecordItemVO, error) { var result models.AppCheckRecordItemVO var details []models.AppCheckRecordItemDetailsVO for _, ri := range ritems { detail := models.AppCheckRecordItemDetailsVO{} item := findItem(citems, ri.CheckItemId) if item == nil { continue } if ri.CheckValue != "" && item.ScopeList != "" { var scopes []*models.CheckItemScopeVO err := json.Unmarshal([]byte(item.ScopeList), &scopes) if err != nil { return result, err } for _, scope := range scopes { if ri.CheckValueIndex == scope.Index { if scope.Type == 1 { result.NormalCount += 1 detail.Alert = false } else { result.AlertCount += 1 detail.Alert = true } detail.ValueIndex = strconv.Itoa(ri.CheckValueIndex) detail.ID = item.Id detail.Value = scope.Value detail.NameCn = item.NameCn detail.NameEn = item.NameEn detail.ReferenceValue = item.ReferenceValue //detail.Describe = item.Details detail.Unit = item.Unit details = append(details, detail) break } } result.Items = details if result.AlertCount > 1 { result.AlertGrade = enums.AlertGradeHIGH } else if result.AlertCount == 1 { result.AlertGrade = enums.AlertGradeMEDIUM } else { result.AlertGrade = enums.AlertGradeNORMAL } result.Describe = enums.AlertGradeMap[result.AlertGrade] } } return result, nil } func formatNumber(num int64, width int) string { format := fmt.Sprintf("%%0%dd", width) return fmt.Sprintf(format, num) } func getUint8(val int) uint8 { return uint8(val & 0xFF) } func indexDigits(ch rune) int { for i, digit := range DIGITS { if ch == digit { return i } } return -1 } func radixString(str string) int64 { sum := int64(0) len := len(str) for i := 0; i < len; i++ { index := indexDigits(rune(str[len-i-1])) sum += int64(index) * int64(math.Pow(64, float64(i))) } return sum } func createCheckRecordItem(items []*models.CheckItem, crId int64, alerts *[]string, vi, n int, crs *service.CheckRecordService) error { item := findItem(items, n) if item == nil { return fmt.Errorf("检测项目不匹配,需要检查基础数据!序号:%v", n) } cri := models.CheckRecordItem{ CheckId: crId, CheckItemId: n, CheckValueIndex: vi, } scopes := []*models.CheckItemScopeVO{} err := json.Unmarshal([]byte(item.ScopeList), &scopes) if err != nil { return fmt.Errorf("检测项目数值范围定义不正确 err:%v", err) } scope := findScope(scopes, vi) if scope == nil { return errors.New("检测结果不匹配") } cri.CheckValue = scope.Value if scope.Type == 1 { *alerts = append(*alerts, strconv.Itoa(n)) } return crs.CreateCheckRecordItem(&cri) } func findScope(scopes []*models.CheckItemScopeVO, vi int) *models.CheckItemScopeVO { for _, scope := range scopes { if scope.Index == vi { return scope } } return nil } func findItem(items []*models.CheckItem, itemNumber int) *models.CheckItem { //循环items for _, item := range items { if item.CheckItemNumber == itemNumber { return item } } return nil }