add unit-tests
This commit is contained in:
parent
7c85ebf016
commit
5c1f958b56
|
@ -229,6 +229,26 @@ func (r *Repository) matchOperationByTxHash(ctx context.Context, txHash string)
|
|||
|
||||
func (r *Repository) FindByChainAndAppId(ctx context.Context, query OperationQuery) ([]*OperationDto, error) {
|
||||
|
||||
pipeline := BuildPipelineSearchByChainAndAppID(query)
|
||||
|
||||
cur, err := r.collections.parsedVaa.Aggregate(ctx, pipeline)
|
||||
if err != nil {
|
||||
r.logger.Error("failed execute aggregation pipeline", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read results from cursor
|
||||
var operations []*OperationDto
|
||||
err = cur.All(ctx, &operations)
|
||||
if err != nil {
|
||||
r.logger.Error("failed to decode cursor", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return operations, nil
|
||||
}
|
||||
|
||||
func BuildPipelineSearchByChainAndAppID(query OperationQuery) mongo.Pipeline {
|
||||
var pipeline mongo.Pipeline
|
||||
|
||||
if len(query.SourceChainIDs) > 0 || len(query.TargetChainIDs) > 0 {
|
||||
|
@ -272,22 +292,7 @@ func (r *Repository) FindByChainAndAppId(ctx context.Context, query OperationQue
|
|||
|
||||
// unset
|
||||
pipeline = append(pipeline, bson.D{{Key: "$unset", Value: bson.A{"transferPrices"}}})
|
||||
|
||||
cur, err := r.collections.parsedVaa.Aggregate(ctx, pipeline)
|
||||
if err != nil {
|
||||
r.logger.Error("failed execute aggregation pipeline", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read results from cursor
|
||||
var operations []*OperationDto
|
||||
err = cur.All(ctx, &operations)
|
||||
if err != nil {
|
||||
r.logger.Error("failed to decode cursor", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return operations, nil
|
||||
return pipeline
|
||||
}
|
||||
|
||||
// FindAll returns all operations filtered by q.
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
package operations_test
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/operations"
|
||||
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var sortStage = bson.D{{"$sort", bson.D{{"timestamp", -1}, {"_id", -1}}}}
|
||||
var skipStage = bson.D{{"$skip", int64(0)}}
|
||||
var limitStage = bson.D{{"$limit", int64(0)}}
|
||||
var lookupVaasStage = bson.D{
|
||||
{"$lookup", bson.D{
|
||||
{"from", "vaas"},
|
||||
{"localField", "_id"},
|
||||
{"foreignField", "_id"},
|
||||
{"as", "vaas"}}}}
|
||||
var lookupTransferPricesStage = bson.D{{"$lookup", bson.D{
|
||||
{"from", "transferPrices"},
|
||||
{"localField", "_id"},
|
||||
{"foreignField", "_id"},
|
||||
{"as", "transferPrices"},
|
||||
}}}
|
||||
var lookupGlobalTransactionsStage = bson.D{{"$lookup", bson.D{
|
||||
{"from", "globalTransactions"},
|
||||
{"localField", "_id"},
|
||||
{"foreignField", "_id"},
|
||||
{"as", "globalTransactions"},
|
||||
}}}
|
||||
var addFieldsStage = bson.D{{"$addFields", bson.D{
|
||||
{"payload", "$parsedPayload"},
|
||||
{"vaa", bson.D{{"$arrayElemAt", bson.A{"$vaas", 0}}}},
|
||||
{"symbol", bson.D{{"$arrayElemAt", bson.A{"$transferPrices.symbol", 0}}}},
|
||||
{"usdAmount", bson.D{{"$arrayElemAt", bson.A{"$transferPrices.usdAmount", 0}}}},
|
||||
{"tokenAmount", bson.D{{"$arrayElemAt", bson.A{"$transferPrices.tokenAmount", 0}}}},
|
||||
{"originTx", bson.D{{"$arrayElemAt", bson.A{"$globalTransactions.originTx", 0}}}},
|
||||
{"destinationTx", bson.D{{"$arrayElemAt", bson.A{"$globalTransactions.destinationTx", 0}}}},
|
||||
}}}
|
||||
var unSetStage = bson.D{{"$unset", bson.A{"transferPrices"}}}
|
||||
|
||||
func TestPipeline_FindByChainAndAppId(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
query operations.OperationQuery
|
||||
expected mongo.Pipeline
|
||||
}{
|
||||
{
|
||||
name: "Search with no query filters",
|
||||
query: operations.OperationQuery{},
|
||||
expected: mongo.Pipeline{
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search with single source_chain ",
|
||||
query: operations.OperationQuery{
|
||||
SourceChainIDs: []sdk.ChainID{1},
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.fromChain": bson.M{"$in": []sdk.ChainID{1}}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search with multiple source_chain ",
|
||||
query: operations.OperationQuery{
|
||||
SourceChainIDs: []sdk.ChainID{1, 2},
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.fromChain": bson.M{"$in": []sdk.ChainID{1, 2}}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search with single target_chain ",
|
||||
query: operations.OperationQuery{
|
||||
TargetChainIDs: []sdk.ChainID{1},
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.toChain": bson.M{"$in": []sdk.ChainID{1}}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search with single target_chain ",
|
||||
query: operations.OperationQuery{
|
||||
TargetChainIDs: []sdk.ChainID{1, 2},
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.toChain": bson.M{"$in": []sdk.ChainID{1, 2}}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search with same source and target chain",
|
||||
query: operations.OperationQuery{
|
||||
SourceChainIDs: []sdk.ChainID{1},
|
||||
TargetChainIDs: []sdk.ChainID{1},
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$or": bson.A{
|
||||
bson.M{"rawStandardizedProperties.fromChain": bson.M{"$in": []sdk.ChainID{1}}},
|
||||
bson.M{"rawStandardizedProperties.toChain": bson.M{"$in": []sdk.ChainID{1}}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search with different source and target chain",
|
||||
query: operations.OperationQuery{
|
||||
SourceChainIDs: []sdk.ChainID{1},
|
||||
TargetChainIDs: []sdk.ChainID{2},
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.fromChain": bson.M{"$in": []sdk.ChainID{1}}},
|
||||
bson.M{"rawStandardizedProperties.toChain": bson.M{"$in": []sdk.ChainID{2}}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search by appID exclusive",
|
||||
query: operations.OperationQuery{
|
||||
AppIDs: []string{"CCTP_WORMHOLE_INTEGRATION", "PORTAL_TOKEN_BRIDGE"},
|
||||
ExclusiveAppId: true,
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"$or": bson.A{
|
||||
bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": "CCTP_WORMHOLE_INTEGRATION"}},
|
||||
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
|
||||
}},
|
||||
bson.M{"$and": bson.A{
|
||||
bson.M{"rawStandardizedProperties.appIds": bson.M{"$eq": "PORTAL_TOKEN_BRIDGE"}},
|
||||
bson.M{"rawStandardizedProperties.appIds": bson.M{"$size": 1}},
|
||||
}},
|
||||
}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Search by appID exclusive false",
|
||||
query: operations.OperationQuery{
|
||||
AppIDs: []string{"CCTP_WORMHOLE_INTEGRATION", "PORTAL_TOKEN_BRIDGE"},
|
||||
ExclusiveAppId: false,
|
||||
},
|
||||
expected: mongo.Pipeline{
|
||||
bson.D{{"$match", bson.M{"rawStandardizedProperties.appIds": bson.M{"$in": []string{"CCTP_WORMHOLE_INTEGRATION", "PORTAL_TOKEN_BRIDGE"}}}}},
|
||||
sortStage,
|
||||
skipStage,
|
||||
limitStage,
|
||||
lookupVaasStage,
|
||||
lookupTransferPricesStage,
|
||||
lookupGlobalTransactionsStage,
|
||||
addFieldsStage,
|
||||
unSetStage,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range cases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result := operations.BuildPipelineSearchByChainAndAppID(testCase.query)
|
||||
assert.Equal(t, testCase.expected, result, "Expected pipeline did not match actual pipeline")
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue