-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests and fix bugs for payer API (#248)
## TL;DR Gets the Payer API service to a mostly working state. ## TODO - Error handling is not great here. What happens when you have a payload that is a mix of envelopes destined for the blockchain and for other nodes, and some of the requests fail. There's no way to roll back across the other services. I think we will need to return more fine-grained error responses that return errors per `ClientEnvelope` instead of having the entire request/response succeed or fail. ## AI Generated Summary ### What changed? - Added `publish_test.go` for the payer API, implementing tests for publishing identity updates and group messages. - Updated `service.go` in the payer package to implement the `PublishClientEnvelopes` method. - Modified existing test files to use `NewTestReplicationAPIClient` instead of `NewTestAPIClient`. - Updated envelope-related functions to provide more specific error messages. - Added `NewPayerAPIClient` function in the API test utilities. - Modified `CreateGroupMessageClientEnvelope` to include a `targetOriginator` parameter. ### How to test? 1. Run the new payer API tests in `publish_test.go`. 2. Verify that existing tests pass with the updated client creation methods. 3. Test the `PublishClientEnvelopes` method of the payer service with various input scenarios. ### Why make this change? This change implements the payer API service, which is crucial for handling client envelope publishing. It also improves test utilities and error messages, making the codebase more robust and easier to debug. The updates to existing tests ensure compatibility with the new payer API functionality. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced a new Payer API client for enhanced functionality. - Added comprehensive unit tests for the Payer API service. - **Improvements** - Enhanced error messages for better clarity in envelope-related functions. - Improved logging and response handling in the PublishClientEnvelopes method. - **Bug Fixes** - Updated API client initialization in various test functions to ensure consistency and accuracy. - **Tests** - Expanded test coverage for group message and client envelope functionalities. - Modified existing tests to adapt to new API client structures and parameters. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Loading branch information
Showing
15 changed files
with
249 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package payer_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
"github.com/xmtp/xmtpd/pkg/abis" | ||
"github.com/xmtp/xmtpd/pkg/api/payer" | ||
"github.com/xmtp/xmtpd/pkg/envelopes" | ||
blockchainMocks "github.com/xmtp/xmtpd/pkg/mocks/blockchain" | ||
registryMocks "github.com/xmtp/xmtpd/pkg/mocks/registry" | ||
"github.com/xmtp/xmtpd/pkg/proto/identity/associations" | ||
envelopesProto "github.com/xmtp/xmtpd/pkg/proto/xmtpv4/envelopes" | ||
"github.com/xmtp/xmtpd/pkg/proto/xmtpv4/payer_api" | ||
"github.com/xmtp/xmtpd/pkg/registry" | ||
"github.com/xmtp/xmtpd/pkg/testutils" | ||
apiTestUtils "github.com/xmtp/xmtpd/pkg/testutils/api" | ||
envelopesTestUtils "github.com/xmtp/xmtpd/pkg/testutils/envelopes" | ||
"github.com/xmtp/xmtpd/pkg/utils" | ||
"google.golang.org/protobuf/proto" | ||
) | ||
|
||
func buildPayerService( | ||
t *testing.T, | ||
) (*payer.Service, *blockchainMocks.MockIBlockchainPublisher, *registryMocks.MockNodeRegistry, func()) { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
log := testutils.NewLog(t) | ||
privKey, err := crypto.GenerateKey() | ||
require.NoError(t, err) | ||
mockRegistry := registryMocks.NewMockNodeRegistry(t) | ||
|
||
require.NoError(t, err) | ||
mockMessagePublisher := blockchainMocks.NewMockIBlockchainPublisher(t) | ||
|
||
payerService, err := payer.NewPayerApiService( | ||
ctx, | ||
log, | ||
mockRegistry, | ||
privKey, | ||
mockMessagePublisher, | ||
) | ||
require.NoError(t, err) | ||
|
||
return payerService, mockMessagePublisher, mockRegistry, func() { | ||
cancel() | ||
} | ||
} | ||
|
||
func TestPublishIdentityUpdate(t *testing.T) { | ||
ctx := context.Background() | ||
svc, mockMessagePublisher, _, cleanup := buildPayerService(t) | ||
defer cleanup() | ||
|
||
inboxId := testutils.RandomInboxId() | ||
inboxIdBytes, err := utils.ParseInboxId(inboxId) | ||
require.NoError(t, err) | ||
|
||
txnHash := common.Hash{1, 2, 3} | ||
sequenceId := uint64(99) | ||
|
||
identityUpdate := &associations.IdentityUpdate{ | ||
InboxId: inboxId, | ||
} | ||
|
||
envelope := envelopesTestUtils.CreateIdentityUpdateClientEnvelope(inboxIdBytes, identityUpdate) | ||
envelopeBytes, err := proto.Marshal(envelope) | ||
require.NoError(t, err) | ||
|
||
mockMessagePublisher.EXPECT(). | ||
PublishIdentityUpdate(mock.Anything, mock.Anything, mock.Anything). | ||
Return(&abis.IdentityUpdatesIdentityUpdateCreated{ | ||
Raw: types.Log{ | ||
TxHash: txnHash, | ||
}, | ||
SequenceId: sequenceId, | ||
Update: envelopeBytes, | ||
}, nil) | ||
|
||
publishResponse, err := svc.PublishClientEnvelopes( | ||
ctx, | ||
&payer_api.PublishClientEnvelopesRequest{ | ||
Envelopes: []*envelopesProto.ClientEnvelope{envelope}, | ||
}, | ||
) | ||
require.NoError(t, err) | ||
require.NotNil(t, publishResponse) | ||
require.Len(t, publishResponse.OriginatorEnvelopes, 1) | ||
|
||
responseEnvelope := publishResponse.OriginatorEnvelopes[0] | ||
parsedOriginatorEnvelope, err := envelopes.NewOriginatorEnvelope(responseEnvelope) | ||
require.NoError(t, err) | ||
|
||
proof := parsedOriginatorEnvelope.Proto().Proof.(*envelopesProto.OriginatorEnvelope_BlockchainProof) | ||
|
||
require.Equal(t, proof.BlockchainProof.TransactionHash, txnHash[:]) | ||
require.Equal( | ||
t, | ||
parsedOriginatorEnvelope.UnsignedOriginatorEnvelope.OriginatorSequenceID(), | ||
sequenceId, | ||
) | ||
} | ||
|
||
func TestPublishToNodes(t *testing.T) { | ||
originatorServer, _, originatorCleanup := apiTestUtils.NewTestAPIServer(t) | ||
defer originatorCleanup() | ||
|
||
ctx := context.Background() | ||
svc, _, mockRegistry, cleanup := buildPayerService(t) | ||
defer cleanup() | ||
|
||
mockRegistry.EXPECT().GetNode(mock.Anything).Return(®istry.Node{ | ||
HttpAddress: formatAddress(originatorServer.Addr().String()), | ||
}, nil) | ||
|
||
groupId := testutils.RandomGroupID() | ||
testGroupMessage := envelopesTestUtils.CreateGroupMessageClientEnvelope( | ||
groupId, | ||
[]byte("test message"), | ||
100, // This is the expected originator ID of the test server | ||
) | ||
|
||
publishResponse, err := svc.PublishClientEnvelopes( | ||
ctx, | ||
&payer_api.PublishClientEnvelopesRequest{ | ||
Envelopes: []*envelopesProto.ClientEnvelope{testGroupMessage}, | ||
}, | ||
) | ||
require.NoError(t, err) | ||
require.NotNil(t, publishResponse) | ||
require.Len(t, publishResponse.OriginatorEnvelopes, 1) | ||
|
||
responseEnvelope := publishResponse.OriginatorEnvelopes[0] | ||
parsedOriginatorEnvelope, err := envelopes.NewOriginatorEnvelope(responseEnvelope) | ||
require.NoError(t, err) | ||
|
||
targetTopic := parsedOriginatorEnvelope.UnsignedOriginatorEnvelope.PayerEnvelope.ClientEnvelope.TargetTopic() | ||
|
||
require.Equal(t, targetTopic.Identifier(), groupId[:]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.