github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/smartcontract/manifest/standard/comply_test.go (about)

     1  package standard
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
     7  	"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func fooMethodBarEvent() *manifest.Manifest {
    12  	return &manifest.Manifest{
    13  		ABI: manifest.ABI{
    14  			Methods: []manifest.Method{
    15  				{
    16  					Name: "foo",
    17  					Parameters: []manifest.Parameter{
    18  						{Type: smartcontract.ByteArrayType},
    19  						{Type: smartcontract.PublicKeyType},
    20  					},
    21  					ReturnType: smartcontract.IntegerType,
    22  					Safe:       true,
    23  				},
    24  			},
    25  			Events: []manifest.Event{
    26  				{
    27  					Name: "bar",
    28  					Parameters: []manifest.Parameter{
    29  						{Type: smartcontract.StringType},
    30  					},
    31  				},
    32  			},
    33  		},
    34  	}
    35  }
    36  
    37  func TestComplyMissingMethod(t *testing.T) {
    38  	m := fooMethodBarEvent()
    39  	m.ABI.GetMethod("foo", -1).Name = "notafoo"
    40  	err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
    41  	require.ErrorIs(t, err, ErrMethodMissing)
    42  }
    43  
    44  func TestComplyInvalidReturnType(t *testing.T) {
    45  	m := fooMethodBarEvent()
    46  	m.ABI.GetMethod("foo", -1).ReturnType = smartcontract.VoidType
    47  	err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
    48  	require.ErrorIs(t, err, ErrInvalidReturnType)
    49  }
    50  
    51  func TestComplyMethodParameterCount(t *testing.T) {
    52  	t.Run("Method", func(t *testing.T) {
    53  		m := fooMethodBarEvent()
    54  		f := m.ABI.GetMethod("foo", -1)
    55  		f.Parameters = append(f.Parameters, manifest.Parameter{Type: smartcontract.BoolType})
    56  		err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
    57  		require.ErrorIs(t, err, ErrMethodMissing)
    58  	})
    59  	t.Run("Event", func(t *testing.T) {
    60  		m := fooMethodBarEvent()
    61  		ev := m.ABI.GetEvent("bar")
    62  		ev.Parameters = ev.Parameters[:0]
    63  		err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
    64  		require.ErrorIs(t, err, ErrInvalidParameterCount)
    65  	})
    66  }
    67  
    68  func TestComplyParameterType(t *testing.T) {
    69  	t.Run("Method", func(t *testing.T) {
    70  		m := fooMethodBarEvent()
    71  		m.ABI.GetMethod("foo", -1).Parameters[0].Type = smartcontract.InteropInterfaceType
    72  		err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
    73  		require.ErrorIs(t, err, ErrInvalidParameterType)
    74  	})
    75  	t.Run("Event", func(t *testing.T) {
    76  		m := fooMethodBarEvent()
    77  		m.ABI.GetEvent("bar").Parameters[0].Type = smartcontract.InteropInterfaceType
    78  		err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
    79  		require.ErrorIs(t, err, ErrInvalidParameterType)
    80  	})
    81  }
    82  
    83  func TestComplyParameterName(t *testing.T) {
    84  	t.Run("Method", func(t *testing.T) {
    85  		m := fooMethodBarEvent()
    86  		m.ABI.GetMethod("foo", -1).Parameters[0].Name = "hehe"
    87  		s := &Standard{Manifest: *fooMethodBarEvent()}
    88  		err := Comply(m, s)
    89  		require.ErrorIs(t, err, ErrInvalidParameterName)
    90  		require.NoError(t, ComplyABI(m, s))
    91  	})
    92  	t.Run("Event", func(t *testing.T) {
    93  		m := fooMethodBarEvent()
    94  		m.ABI.GetEvent("bar").Parameters[0].Name = "hehe"
    95  		s := &Standard{Manifest: *fooMethodBarEvent()}
    96  		err := Comply(m, s)
    97  		require.ErrorIs(t, err, ErrInvalidParameterName)
    98  		require.NoError(t, ComplyABI(m, s))
    99  	})
   100  }
   101  
   102  func TestMissingEvent(t *testing.T) {
   103  	m := fooMethodBarEvent()
   104  	m.ABI.GetEvent("bar").Name = "notabar"
   105  	err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
   106  	require.ErrorIs(t, err, ErrEventMissing)
   107  }
   108  
   109  func TestSafeFlag(t *testing.T) {
   110  	m := fooMethodBarEvent()
   111  	m.ABI.GetMethod("foo", -1).Safe = false
   112  	err := Comply(m, &Standard{Manifest: *fooMethodBarEvent()})
   113  	require.ErrorIs(t, err, ErrSafeMethodMismatch)
   114  }
   115  
   116  func TestComplyValid(t *testing.T) {
   117  	m := fooMethodBarEvent()
   118  	m.ABI.Methods = append(m.ABI.Methods, manifest.Method{
   119  		Name:       "newmethod",
   120  		Offset:     123,
   121  		ReturnType: smartcontract.ByteArrayType,
   122  	})
   123  	m.ABI.Events = append(m.ABI.Events, manifest.Event{
   124  		Name: "otherevent",
   125  		Parameters: []manifest.Parameter{{
   126  			Name: "names do not matter",
   127  			Type: smartcontract.IntegerType,
   128  		}},
   129  	})
   130  	require.NoError(t, Comply(m, &Standard{Manifest: *fooMethodBarEvent()}))
   131  }
   132  
   133  func TestCheck(t *testing.T) {
   134  	m := manifest.NewManifest("Test")
   135  	require.Error(t, Check(m, manifest.NEP17StandardName))
   136  
   137  	m.ABI.Methods = append(m.ABI.Methods, DecimalTokenBase.ABI.Methods...)
   138  	m.ABI.Methods = append(m.ABI.Methods, Nep17.ABI.Methods...)
   139  	m.ABI.Events = append(m.ABI.Events, Nep17.ABI.Events...)
   140  	require.NoError(t, Check(m, manifest.NEP17StandardName))
   141  	require.NoError(t, CheckABI(m, manifest.NEP17StandardName))
   142  }
   143  
   144  func TestOptional(t *testing.T) {
   145  	var m Standard
   146  	m.Optional = []manifest.Method{{
   147  		Name:       "optMet",
   148  		Parameters: []manifest.Parameter{{Type: smartcontract.ByteArrayType}},
   149  		ReturnType: smartcontract.IntegerType,
   150  	}}
   151  
   152  	t.Run("wrong parameter count, do not check", func(t *testing.T) {
   153  		var actual manifest.Manifest
   154  		actual.ABI.Methods = []manifest.Method{{
   155  			Name:       "optMet",
   156  			ReturnType: smartcontract.IntegerType,
   157  		}}
   158  		require.NoError(t, Comply(&actual, &m))
   159  	})
   160  	t.Run("good parameter count, bad return", func(t *testing.T) {
   161  		var actual manifest.Manifest
   162  		actual.ABI.Methods = []manifest.Method{{
   163  			Name:       "optMet",
   164  			Parameters: []manifest.Parameter{{Type: smartcontract.ArrayType}},
   165  			ReturnType: smartcontract.IntegerType,
   166  		}}
   167  		require.Error(t, Comply(&actual, &m))
   168  	})
   169  	t.Run("good parameter count, good return", func(t *testing.T) {
   170  		var actual manifest.Manifest
   171  		actual.ABI.Methods = []manifest.Method{{
   172  			Name:       "optMet",
   173  			Parameters: []manifest.Parameter{{Type: smartcontract.ByteArrayType}},
   174  			ReturnType: smartcontract.IntegerType,
   175  		}}
   176  		require.NoError(t, Comply(&actual, &m))
   177  	})
   178  }