diff --git a/example_test.go b/example_test.go new file mode 100644 index 0000000..ac2173b --- /dev/null +++ b/example_test.go @@ -0,0 +1,113 @@ +package sdk_LinkedMall + +import ( + "testing" +) + +// TestNewClient 校验客户端初始化(不发起网络请求)。 +func TestNewClient(t *testing.T) { + cli, err := NewClient("test-access-key-id", "test-access-key-secret") + if err != nil { + t.Fatalf("NewClient() error = %v", err) + } + if cli == nil { + t.Fatal("NewClient() returned nil client") + } +} + +// TestNewLinkedMallClient 校验别名构造函数。 +func TestNewLinkedMallClient(t *testing.T) { + cli, err := NewLinkedMallClient("test-access-key-id", "test-access-key-secret") + if err != nil { + t.Fatalf("NewLinkedMallClient() error = %v", err) + } + if cli == nil { + t.Fatal("NewLinkedMallClient() returned nil client") + } +} + +// TestStructToQuery 校验请求结构体到 query 参数的转换。 +func TestStructToQuery(t *testing.T) { + req := &ListPurchaserShopsRequest{PageNum: 1, PageSize: 20} + q := structToQuery(req) + if got := q["PageNum"]; got == nil || *got != "1" { + t.Errorf("PageNum = %v, want 1", got) + } + if got := q["PageSize"]; got == nil || *got != "20" { + t.Errorf("PageSize = %v, want 20", got) + } +} + +// TestStructToQuerySkipEmpty 校验零值字段被忽略。 +func TestStructToQuerySkipEmpty(t *testing.T) { + req := &ListSelectionProductsRequest{PurchaserId: "p-001"} + q := structToQuery(req) + if q["PageNum"] != nil { + t.Errorf("PageNum should be omitted, got %v", *q["PageNum"]) + } + if got := q["PurchaserId"]; got == nil || *got != "p-001" { + t.Errorf("PurchaserId = %v, want p-001", got) + } +} + +// TestBuildPath 校验路径占位符替换。 +func TestBuildPath(t *testing.T) { + path := buildPath("/orders/{OrderId}/logistics", map[string]string{"OrderId": "O123"}) + if path != "/orders/O123/logistics" { + t.Errorf("buildPath() = %s, want /orders/O123/logistics", path) + } +} + +// TestMarshalJSON 校验 int64 金额序列化不丢失精度。 +func TestMarshalJSON(t *testing.T) { + b, err := MarshalJSON(map[string]int64{"amount": 123456789}) + if err != nil { + t.Fatalf("MarshalJSON() error = %v", err) + } + if string(b) != `{"amount":123456789}` { + t.Errorf("MarshalJSON() = %s, want {\"amount\":123456789}", string(b)) + } +} + +// TestParseCallbackEvent 校验回调事件解析。 +func TestParseCallbackEvent(t *testing.T) { + body := []byte(`{ + "EventCode":"PURCHASE_ORDER_CHANGE", + "PurchaseOrderId":"PO123", + "OrderIdList":["O1","O2"], + "Status":"SUCCESS", + "RequestId":"R1" + }`) + evt, err := ParseCallbackEvent(body) + if err != nil { + t.Fatalf("ParseCallbackEvent() error = %v", err) + } + if evt.EventCode != EventCodePurchaseOrderChange { + t.Errorf("EventCode = %s, want %s", evt.EventCode, EventCodePurchaseOrderChange) + } + if evt.PurchaseOrderId != "PO123" || len(evt.OrderIdList) != 2 { + t.Errorf("unexpected callback event: %+v", evt) + } + if got := string(CallbackSuccessBody()); got != "{\"success\":true}" { + t.Errorf("CallbackSuccessBody() = %s", got) + } +} + +// TestCheckSuccess 校验业务成功判断与错误码匹配。 +func TestCheckSuccess(t *testing.T) { + ok := &CommonResponse{Success: true, Code: "SUCCESS", RequestId: "r1"} + if err := CheckSuccess(ok); err != nil { + t.Errorf("CheckSuccess(success) error = %v", err) + } + fail := &CommonResponse{ + Success: false, Code: CodeOrderNotFound, + Message: "order not found", SubCode: "OrderNotFound", + } + err := CheckSuccess(fail) + if err == nil { + t.Fatal("CheckSuccess(fail) should return error") + } + if !IsCode(fail, CodeOrderNotFound) { + t.Error("IsCode(OrderNotFound) should be true") + } +} \ No newline at end of file