FinnTew commented on code in PR #968:
URL: 
https://github.com/apache/incubator-seata-go/pull/968#discussion_r2506498664


##########
pkg/integration/dubbo/dubbo_transaction_filter_test.go:
##########
@@ -90,3 +96,280 @@ func TestDubboTransactionFilterOnResponse(t *testing.T) {
                })
        }
 }
+
+type mockInvocation struct {
+       attachments map[string]interface{}
+}
+
+func newMockInvocation() *mockInvocation {
+       return &mockInvocation{
+               attachments: make(map[string]interface{}),
+       }
+}
+
+func (m *mockInvocation) MethodName() string                  { return 
"mockMethod" }
+func (m *mockInvocation) ParameterTypeNames() []string        { return nil }
+func (m *mockInvocation) ParameterTypes() []reflect.Type      { return nil }
+func (m *mockInvocation) ParameterValues() []reflect.Value    { return nil }
+func (m *mockInvocation) Arguments() []interface{}            { return nil }
+func (m *mockInvocation) Reply() interface{}                  { return nil }
+func (m *mockInvocation) Attachments() map[string]interface{} { return 
m.attachments }
+func (m *mockInvocation) Attributes() map[string]interface{}  { return nil }
+func (m *mockInvocation) AttributeByKey(key string, defaultValue interface{}) 
interface{} {
+       return nil
+}
+func (m *mockInvocation) SetAttachment(key string, value interface{}) {
+       m.attachments[key] = value
+}
+func (m *mockInvocation) GetAttachment(key string) (string, bool) {
+       if val, ok := m.attachments[key]; ok {
+               if str, ok := val.(string); ok {
+                       return str, true
+               }
+       }
+       return "", false
+}
+func (m *mockInvocation) GetAttachmentWithDefaultValue(key, defaultValue 
string) string {
+       if val, ok := m.GetAttachment(key); ok {
+               return val
+       }
+       return defaultValue
+}
+func (m *mockInvocation) ServiceKey() string                  { return "" }
+func (m *mockInvocation) Invoker() protocol.Invoker           { return nil }
+func (m *mockInvocation) SetInvoker(invoker protocol.Invoker) {}
+func (m *mockInvocation) ActualMethodName() string            { return 
"mockMethod" }
+func (m *mockInvocation) IsGenericInvocation() bool           { return false }
+func (m *mockInvocation) GetAttachmentInterface(key string) interface{} {
+       return m.attachments[key]
+}
+func (m *mockInvocation) GetAttachmentAsContext() context.Context     { return 
context.Background() }
+func (m *mockInvocation) SetAttribute(key string, value interface{})  {}
+func (m *mockInvocation) GetAttribute(key string) (interface{}, bool) { return 
nil, false }
+func (m *mockInvocation) GetAttributeWithDefaultValue(key string, defaultValue 
interface{}) interface{} {
+       return defaultValue
+}
+
+type mockInvoker struct {
+       invoked    bool
+       invokeFunc func(context.Context, protocol.Invocation) protocol.Result
+}
+
+func (m *mockInvoker) GetURL() *common.URL { return nil }
+func (m *mockInvoker) IsAvailable() bool   { return true }
+func (m *mockInvoker) Destroy()            {}
+func (m *mockInvoker) Invoke(ctx context.Context, invocation 
protocol.Invocation) protocol.Result {
+       m.invoked = true
+       if m.invokeFunc != nil {
+               return m.invokeFunc(ctx, invocation)
+       }
+       return &mockResult{}
+}
+
+type mockResult struct {
+       err   error
+       value interface{}
+}
+
+func (m *mockResult) SetError(err error)                         { m.err = err 
}
+func (m *mockResult) Error() error                               { return 
m.err }
+func (m *mockResult) SetResult(value interface{})                { m.value = 
value }
+func (m *mockResult) Result() interface{}                        { return 
m.value }
+func (m *mockResult) SetAttachments(map[string]interface{})      {}
+func (m *mockResult) Attachments() map[string]interface{}        { return nil }
+func (m *mockResult) AddAttachment(string, interface{})          {}
+func (m *mockResult) Attachment(string, interface{}) interface{} { return nil }
+
+// TestInvoke_WithXidInContext tests Invoke when XID exists in context
+func TestInvoke_WithXidInContext(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       ctx := tm.InitSeataContext(context.Background())
+       tm.SetXID(ctx, "context-xid-123")
+
+       invocation := newMockInvocation()
+       invoker := &mockInvoker{}
+
+       result := filter.Invoke(ctx, invoker, invocation)
+
+       assert.NotNil(t, result)
+       assert.True(t, invoker.invoked)
+
+       // Verify XID was set in attachments for dubbo-go
+       seataXid, ok := invocation.GetAttachment(constant.SeataXidKey)
+       assert.True(t, ok)
+       assert.Equal(t, "context-xid-123", seataXid)
+
+       // Verify XID was set in attachments for dubbo-java
+       txXid, ok := invocation.GetAttachment(constant.XidKey)
+       assert.True(t, ok)
+       assert.Equal(t, "context-xid-123", txXid)
+}
+
+// TestInvoke_WithRpcXidOnly tests Invoke when XID only exists in RPC 
attachment
+func TestInvoke_WithRpcXidOnly(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       ctx := context.Background()
+
+       invocation := newMockInvocation()
+       invocation.SetAttachment(constant.SeataXidKey, "rpc-xid-456")
+
+       var capturedCtx context.Context
+       invoker := &mockInvoker{
+               invokeFunc: func(ctx context.Context, inv protocol.Invocation) 
protocol.Result {
+                       capturedCtx = ctx
+                       return &mockResult{}
+               },
+       }
+
+       result := filter.Invoke(ctx, invoker, invocation)
+
+       assert.NotNil(t, result)
+       assert.True(t, invoker.invoked)
+
+       // Verify XID was set in context
+       xid := tm.GetXID(capturedCtx)
+       assert.Equal(t, "rpc-xid-456", xid)
+}
+
+// TestInvoke_NoXid tests Invoke when no XID exists
+func TestInvoke_NoXid(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       ctx := context.Background()
+
+       invocation := newMockInvocation()
+       invoker := &mockInvoker{}
+
+       result := filter.Invoke(ctx, invoker, invocation)
+
+       assert.NotNil(t, result)
+       assert.True(t, invoker.invoked)
+}
+
+// TestGetRpcXid_DubboGo tests getRpcXid with dubbo-go format
+func TestGetRpcXid_DubboGo(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       invocation := newMockInvocation()
+       invocation.SetAttachment(constant.SeataXidKey, "dubbo-go-xid")
+
+       xid := filter.getRpcXid(invocation)
+
+       assert.Equal(t, "dubbo-go-xid", xid)
+}
+
+// TestGetRpcXid_DubboGoLowercase tests getRpcXid with lowercase dubbo-go 
format
+func TestGetRpcXid_DubboGoLowercase(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       invocation := newMockInvocation()
+       invocation.SetAttachment(strings.ToLower(constant.SeataXidKey), 
"dubbo-go-lower-xid")
+
+       xid := filter.getRpcXid(invocation)
+
+       assert.Equal(t, "dubbo-go-lower-xid", xid)
+}
+
+// TestGetRpcXid_DubboJava tests getRpcXid with dubbo-java format
+func TestGetRpcXid_DubboJava(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       invocation := newMockInvocation()
+       invocation.SetAttachment(constant.XidKey, "dubbo-java-xid")
+
+       xid := filter.getRpcXid(invocation)
+
+       assert.Equal(t, "dubbo-java-xid", xid)
+}
+
+// TestGetRpcXid_DubboJavaLowercase tests getRpcXid with lowercase dubbo-java 
format
+func TestGetRpcXid_DubboJavaLowercase(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       invocation := newMockInvocation()
+       invocation.SetAttachment(strings.ToLower(constant.XidKey), 
"dubbo-java-lower-xid")
+
+       xid := filter.getRpcXid(invocation)
+
+       assert.Equal(t, "dubbo-java-lower-xid", xid)
+}
+
+// TestGetRpcXid_Precedence tests that dubbo-go XID takes precedence over 
dubbo-java
+func TestGetRpcXid_Precedence(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       invocation := newMockInvocation()
+       invocation.SetAttachment(constant.SeataXidKey, "dubbo-go-xid")
+       invocation.SetAttachment(constant.XidKey, "dubbo-java-xid")
+
+       xid := filter.getRpcXid(invocation)
+
+       assert.Equal(t, "dubbo-go-xid", xid, "dubbo-go XID should take 
precedence")
+}
+
+// TestGetRpcXid_Empty tests getRpcXid with no XID
+func TestGetRpcXid_Empty(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+       invocation := newMockInvocation()
+
+       xid := filter.getRpcXid(invocation)
+
+       assert.Equal(t, "", xid)
+}
+
+// TestGetDubboGoRpcXid tests getDubboGoRpcXid method
+func TestGetDubboGoRpcXid(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+
+       t.Run("with_seata_xid", func(t *testing.T) {
+               inv := newMockInvocation()
+               inv.SetAttachment(constant.SeataXidKey, "go-xid-1")
+
+               xid := filter.getDubboGoRpcXid(inv)
+               assert.Equal(t, "go-xid-1", xid)
+       })
+
+       t.Run("with_lowercase_seata_xid", func(t *testing.T) {
+               inv := newMockInvocation()
+               inv.SetAttachment(strings.ToLower(constant.SeataXidKey), 
"go-xid-lower")
+
+               xid := filter.getDubboGoRpcXid(inv)
+               assert.Equal(t, "go-xid-lower", xid)
+       })
+
+       t.Run("empty", func(t *testing.T) {
+               inv := newMockInvocation()
+
+               xid := filter.getDubboGoRpcXid(inv)
+               assert.Equal(t, "", xid)
+       })
+}
+
+// TestGetDubboJavaRpcXid tests getDubboJavaRpcXid method
+func TestGetDubboJavaRpcXid(t *testing.T) {
+       filter := &dubboTransactionFilter{}
+
+       t.Run("with_xid_key", func(t *testing.T) {

Review Comment:
   Organize multiple unit test cases using a table-driven approach.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to