status-go/t/e2e/services/personal_sign_test.go

222 lines
6.5 KiB
Go
Raw Normal View History

package services
import (
"encoding/json"
"fmt"
"testing"
"github.com/ethereum/go-ethereum/accounts/keystore"
acc "github.com/status-im/status-go/geth/account"
"github.com/status-im/status-go/geth/params"
"github.com/status-im/status-go/geth/signal"
"github.com/status-im/status-go/services/personal"
"github.com/status-im/status-go/sign"
e2e "github.com/status-im/status-go/t/e2e"
. "github.com/status-im/status-go/t/utils"
"github.com/stretchr/testify/suite"
)
const (
signDataString = "0xBAADBEEF"
accountNotExists = "0x00164ca341326a03b547c05B343b2E21eFAe2400"
)
type testParams struct {
Title string
EnableUpstream bool
Account string
Password string
HandlerFactory func(string, string) func(string)
ExpectedError error
DontSelectAccount bool // to take advantage of the fact, that the default is `false`
}
func TestPersonalSignSuite(t *testing.T) {
s := new(PersonalSignSuite)
s.upstream = false
suite.Run(t, s)
}
func TestPersonalSignSuiteUpstream(t *testing.T) {
s := new(PersonalSignSuite)
s.upstream = true
suite.Run(t, s)
}
type PersonalSignSuite struct {
e2e.BackendTestSuite
upstream bool
}
func (s *PersonalSignSuite) TestPersonalSignSuccess() {
s.testPersonalSign(testParams{
Account: TestConfig.Account1.Address,
Password: TestConfig.Account1.Password,
})
}
func (s *PersonalSignSuite) TestPersonalSignWrongPassword() {
s.testPersonalSign(testParams{
Account: TestConfig.Account1.Address,
Password: TestConfig.Account1.Password,
HandlerFactory: s.notificationHandlerWrongPassword,
})
}
func (s *PersonalSignSuite) TestPersonalSignNoSuchAccount() {
s.testPersonalSign(testParams{
Account: accountNotExists,
Password: TestConfig.Account1.Password,
ExpectedError: personal.ErrInvalidPersonalSignAccount,
HandlerFactory: s.notificationHandlerNoAccount,
})
}
func (s *PersonalSignSuite) TestPersonalSignWrongAccount() {
s.testPersonalSign(testParams{
Account: TestConfig.Account2.Address,
Password: TestConfig.Account2.Password,
ExpectedError: personal.ErrInvalidPersonalSignAccount,
HandlerFactory: s.notificationHandlerInvalidAccount,
})
}
func (s *PersonalSignSuite) TestPersonalSignNoAccountSelected() {
s.testPersonalSign(testParams{
Account: TestConfig.Account1.Address,
Password: TestConfig.Account1.Password,
HandlerFactory: s.notificationHandlerNoAccountSelected,
DontSelectAccount: true,
})
}
// Utility methods
func (s *PersonalSignSuite) notificationHandlerSuccess(account string, pass string) func(string) {
return func(jsonEvent string) {
s.notificationHandler(account, pass, nil)(jsonEvent)
}
}
func (s *PersonalSignSuite) notificationHandlerWrongPassword(account string, pass string) func(string) {
return func(jsonEvent string) {
s.notificationHandler(account, pass+"wrong", keystore.ErrDecrypt)(jsonEvent)
s.notificationHandlerSuccess(account, pass)(jsonEvent)
}
}
func (s *PersonalSignSuite) notificationHandlerNoAccount(account string, pass string) func(string) {
return func(jsonEvent string) {
s.notificationHandler(account, pass, personal.ErrInvalidPersonalSignAccount)(jsonEvent)
}
}
func (s *PersonalSignSuite) notificationHandlerInvalidAccount(account string, pass string) func(string) {
return func(jsonEvent string) {
s.notificationHandler(account, pass, personal.ErrInvalidPersonalSignAccount)(jsonEvent)
}
}
func (s *PersonalSignSuite) notificationHandlerNoAccountSelected(account string, pass string) func(string) {
return func(jsonEvent string) {
s.notificationHandler(account, pass, acc.ErrNoAccountSelected)(jsonEvent)
envelope := unmarshalEnvelope(jsonEvent)
if envelope.Type == sign.EventSignRequestAdded {
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
s.NoError(err)
}
s.notificationHandlerSuccess(account, pass)(jsonEvent)
}
}
func (s *PersonalSignSuite) initTest(upstreamEnabled bool) error {
nodeConfig, err := MakeTestNodeConfig(GetNetworkID())
s.NoError(err)
nodeConfig.IPCEnabled = false
nodeConfig.HTTPHost = "" // to make sure that no HTTP interface is started
if upstreamEnabled {
networkURL, err := GetRemoteURL()
s.NoError(err)
nodeConfig.UpstreamConfig.Enabled = true
nodeConfig.UpstreamConfig.URL = networkURL
}
return s.Backend.StartNode(nodeConfig)
}
func (s *PersonalSignSuite) notificationHandler(account string, pass string, expectedError error) func(string) {
return func(jsonEvent string) {
envelope := unmarshalEnvelope(jsonEvent)
if envelope.Type == sign.EventSignRequestAdded {
event := envelope.Event.(map[string]interface{})
id := event["id"].(string)
s.T().Logf("Sign request added (will be completed shortly): {id: %s}\n", id)
//check for the correct method name
method := event["method"].(string)
s.Equal(params.PersonalSignMethodName, method)
//check the event data
args := event["args"].(map[string]interface{})
s.Equal(signDataString, args["data"].(string))
s.Equal(account, args["account"].(string))
e := s.Backend.ApproveSignRequest(id, pass).Error
s.T().Logf("Sign request approved. {id: %s, acc: %s, err: %v}", id, account, e)
if expectedError == nil {
s.NoError(e, "cannot complete sign reauest[%v]: %v", id, e)
} else {
s.EqualError(e, expectedError.Error())
}
}
}
}
func (s *PersonalSignSuite) testPersonalSign(testParams testParams) {
// Test upstream if that's not StatusChain
if s.upstream && GetNetworkID() == params.StatusChainNetworkID {
s.T().Skip()
return
}
if testParams.HandlerFactory == nil {
testParams.HandlerFactory = s.notificationHandlerSuccess
}
err := s.initTest(s.upstream)
s.NoError(err)
defer func() {
err := s.Backend.StopNode()
s.NoError(err)
}()
signal.SetDefaultNodeNotificationHandler(testParams.HandlerFactory(testParams.Account, testParams.Password))
if testParams.DontSelectAccount {
s.NoError(s.Backend.Logout())
} else {
s.NoError(s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
}
basicCall := fmt.Sprintf(
`{"jsonrpc":"2.0","method":"personal_sign","params":["%s", "%s"],"id":67}`,
signDataString,
testParams.Account)
result := s.Backend.CallRPC(basicCall)
if testParams.ExpectedError == nil {
s.NotContains(result, "error")
} else {
s.Contains(result, testParams.ExpectedError.Error())
}
}
func unmarshalEnvelope(jsonEvent string) signal.Envelope {
var envelope signal.Envelope
if e := json.Unmarshal([]byte(jsonEvent), &envelope); e != nil {
panic(e)
}
return envelope
}