github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/nns/contract_test.go (about)

     1  package nns
     2  
     3  import (
     4  	"errors"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"github.com/google/uuid"
     9  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
    10  	"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
    11  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
    12  	"github.com/nspcc-dev/neo-go/pkg/util"
    13  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  type testAct struct {
    18  	err error
    19  	res *result.Invoke
    20  	tx  *transaction.Transaction
    21  	txh util.Uint256
    22  	vub uint32
    23  }
    24  
    25  func (t *testAct) Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error) {
    26  	return t.res, t.err
    27  }
    28  func (t *testAct) CallAndExpandIterator(contract util.Uint160, method string, maxItems int, params ...any) (*result.Invoke, error) {
    29  	return t.res, t.err
    30  }
    31  func (t *testAct) TerminateSession(sessionID uuid.UUID) error {
    32  	return t.err
    33  }
    34  func (t *testAct) TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error) {
    35  	return t.res.Stack, t.err
    36  }
    37  
    38  func (t *testAct) MakeRun(script []byte) (*transaction.Transaction, error) {
    39  	return t.tx, t.err
    40  }
    41  func (t *testAct) MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error) {
    42  	return t.tx, t.err
    43  }
    44  func (t *testAct) SendRun(script []byte) (util.Uint256, uint32, error) {
    45  	return t.txh, t.vub, t.err
    46  }
    47  func (t *testAct) MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error) {
    48  	return t.tx, t.err
    49  }
    50  func (t *testAct) MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error) {
    51  	return t.tx, t.err
    52  }
    53  func (t *testAct) SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error) {
    54  	return t.txh, t.vub, t.err
    55  }
    56  
    57  func (t *testAct) SignAndSend(tx *transaction.Transaction) (util.Uint256, uint32, error) {
    58  	return t.txh, t.vub, t.err
    59  }
    60  
    61  func TestSimpleGetters(t *testing.T) {
    62  	ta := &testAct{}
    63  	nns := NewReader(ta, util.Uint160{1, 2, 3})
    64  
    65  	ta.err = errors.New("")
    66  	_, err := nns.GetPrice(uint8(A))
    67  	require.Error(t, err)
    68  	_, err = nns.IsAvailable("nspcc.neo")
    69  	require.Error(t, err)
    70  	_, err = nns.Resolve("nspcc.neo", A)
    71  	require.Error(t, err)
    72  	_, err = nns.GetRecord("nspcc.neo", A)
    73  	require.Error(t, err)
    74  
    75  	ta.err = nil
    76  	ta.res = &result.Invoke{
    77  		State: "HALT",
    78  		Stack: []stackitem.Item{
    79  			stackitem.Make(100500),
    80  		},
    81  	}
    82  	price, err := nns.GetPrice(uint8(A))
    83  	require.NoError(t, err)
    84  	require.Equal(t, new(big.Int).SetInt64(100500), price)
    85  
    86  	ta.res = &result.Invoke{
    87  		State: "HALT",
    88  		Stack: []stackitem.Item{
    89  			stackitem.Make(true),
    90  		},
    91  	}
    92  	ava, err := nns.IsAvailable("nspcc.neo")
    93  	require.NoError(t, err)
    94  	require.Equal(t, true, ava)
    95  
    96  	ta.res = &result.Invoke{
    97  		State: "HALT",
    98  		Stack: []stackitem.Item{
    99  			stackitem.Make("some text"),
   100  		},
   101  	}
   102  	txt, err := nns.Resolve("nspcc.neo", TXT)
   103  	require.NoError(t, err)
   104  	require.Equal(t, "some text", txt)
   105  
   106  	rec, err := nns.GetRecord("nspcc.neo", TXT)
   107  	require.NoError(t, err)
   108  	require.Equal(t, "some text", rec)
   109  }
   110  
   111  func TestGetAllRecords(t *testing.T) {
   112  	ta := &testAct{}
   113  	nns := NewReader(ta, util.Uint160{1, 2, 3})
   114  
   115  	ta.err = errors.New("")
   116  	_, err := nns.GetAllRecords("nspcc.neo")
   117  	require.Error(t, err)
   118  
   119  	ta.err = nil
   120  	iid := uuid.New()
   121  	ta.res = &result.Invoke{
   122  		State: "HALT",
   123  		Stack: []stackitem.Item{
   124  			stackitem.NewInterop(result.Iterator{
   125  				ID: &iid,
   126  			}),
   127  		},
   128  	}
   129  	_, err = nns.GetAllRecords("nspcc.neo")
   130  	require.Error(t, err)
   131  
   132  	// Session-based iterator.
   133  	sid := uuid.New()
   134  	ta.res = &result.Invoke{
   135  		Session: sid,
   136  		State:   "HALT",
   137  		Stack: []stackitem.Item{
   138  			stackitem.NewInterop(result.Iterator{
   139  				ID: &iid,
   140  			}),
   141  		},
   142  	}
   143  	iter, err := nns.GetAllRecords("nspcc.neo")
   144  	require.NoError(t, err)
   145  
   146  	ta.res = &result.Invoke{
   147  		Stack: []stackitem.Item{
   148  			stackitem.Make([]stackitem.Item{
   149  				stackitem.Make("n3"),
   150  				stackitem.Make(16),
   151  				stackitem.Make("cool"),
   152  			}),
   153  		},
   154  	}
   155  	vals, err := iter.Next(10)
   156  	require.NoError(t, err)
   157  	require.Equal(t, 1, len(vals))
   158  	require.Equal(t, RecordState{
   159  		Name: "n3",
   160  		Type: TXT,
   161  		Data: "cool",
   162  	}, vals[0])
   163  
   164  	ta.err = errors.New("")
   165  	_, err = iter.Next(1)
   166  	require.Error(t, err)
   167  
   168  	err = iter.Terminate()
   169  	require.Error(t, err)
   170  
   171  	// Value-based iterator.
   172  	ta.err = nil
   173  	ta.res = &result.Invoke{
   174  		State: "HALT",
   175  		Stack: []stackitem.Item{
   176  			stackitem.NewInterop(result.Iterator{
   177  				Values: []stackitem.Item{
   178  					stackitem.Make("n3"),
   179  					stackitem.Make(16),
   180  					stackitem.Make("cool"),
   181  				},
   182  			}),
   183  		},
   184  	}
   185  	iter, err = nns.GetAllRecords("nspcc.neo")
   186  	require.NoError(t, err)
   187  
   188  	ta.err = errors.New("")
   189  	err = iter.Terminate()
   190  	require.NoError(t, err)
   191  
   192  	ta.err = nil
   193  	ta.res = &result.Invoke{
   194  		State: "HALT",
   195  		Stack: []stackitem.Item{
   196  			stackitem.NewInterop(result.Iterator{
   197  				Values: []stackitem.Item{
   198  					stackitem.Make("valid data"),
   199  					stackitem.Make(-1),
   200  				},
   201  			}),
   202  		},
   203  	}
   204  	iter, err = nns.GetAllRecords("nspcc.neo")
   205  	require.NoError(t, err)
   206  
   207  	_, err = iter.Next(10)
   208  
   209  	require.Error(t, err)
   210  	require.Contains(t, err.Error(), "item #0: ")
   211  }
   212  
   213  func TestGetAllRecordsExpanded(t *testing.T) {
   214  	ta := &testAct{}
   215  	nns := NewReader(ta, util.Uint160{1, 2, 3})
   216  
   217  	ta.err = errors.New("")
   218  	_, err := nns.GetAllRecordsExpanded("nspcc.neo", 8)
   219  	require.Error(t, err)
   220  
   221  	ta.err = nil
   222  	ta.res = &result.Invoke{
   223  		State: "HALT",
   224  		Stack: []stackitem.Item{
   225  			stackitem.Make(42),
   226  		},
   227  	}
   228  	_, err = nns.GetAllRecordsExpanded("nspcc.neo", 8)
   229  	require.Error(t, err)
   230  
   231  	ta.res = &result.Invoke{
   232  		State: "HALT",
   233  		Stack: []stackitem.Item{
   234  			stackitem.Make([]stackitem.Item{
   235  				stackitem.Make([]stackitem.Item{
   236  					stackitem.Make("n3"),
   237  					stackitem.Make(16),
   238  					stackitem.Make("cool"),
   239  				}),
   240  			}),
   241  		},
   242  	}
   243  	vals, err := nns.GetAllRecordsExpanded("nspcc.neo", 8)
   244  	require.NoError(t, err)
   245  	require.Equal(t, 1, len(vals))
   246  	require.Equal(t, RecordState{
   247  		Name: "n3",
   248  		Type: TXT,
   249  		Data: "cool",
   250  	}, vals[0])
   251  }
   252  
   253  func TestRoots(t *testing.T) {
   254  	ta := &testAct{}
   255  	nns := NewReader(ta, util.Uint160{1, 2, 3})
   256  	ta.err = errors.New("")
   257  	_, err := nns.Roots()
   258  	require.Error(t, err)
   259  	iid := uuid.New()
   260  
   261  	// Session-based iterator.
   262  	sid := uuid.New()
   263  	ta.res = &result.Invoke{
   264  		Session: sid,
   265  		State:   "HALT",
   266  		Stack: []stackitem.Item{
   267  			stackitem.NewInterop(result.Iterator{
   268  				ID: &iid,
   269  			}),
   270  		},
   271  	}
   272  	ta.err = nil
   273  	iter, err := nns.Roots()
   274  	require.NoError(t, err)
   275  
   276  	ta.res = &result.Invoke{
   277  		Stack: []stackitem.Item{
   278  			stackitem.Make([]stackitem.Item{
   279  				stackitem.Make("n3"),
   280  				stackitem.Make("aaaaaa"),
   281  				stackitem.Make("cool"),
   282  			}),
   283  		},
   284  	}
   285  	vals, err := iter.Next(10)
   286  	require.NoError(t, err)
   287  	require.Equal(t, 1, len(vals))
   288  	require.Equal(t, "n3", vals[0])
   289  
   290  	ta.err = errors.New("")
   291  	_, err = iter.Next(1)
   292  	require.Error(t, err)
   293  
   294  	err = iter.Terminate()
   295  	require.Error(t, err)
   296  
   297  	// Value-based iterator.
   298  	ta.err = nil
   299  	ta.res = &result.Invoke{
   300  		State: "HALT",
   301  		Stack: []stackitem.Item{
   302  			stackitem.NewInterop(result.Iterator{
   303  				Values: []stackitem.Item{
   304  					stackitem.Make("n3"),
   305  					stackitem.Make("aaaaaa"),
   306  					stackitem.Make("cool"),
   307  				},
   308  			}),
   309  		},
   310  	}
   311  	iter, err = nns.Roots()
   312  	require.NoError(t, err)
   313  
   314  	ta.err = errors.New("")
   315  	err = iter.Terminate()
   316  	require.NoError(t, err)
   317  
   318  	sid = uuid.New()
   319  	iid = uuid.New()
   320  	ta.res = &result.Invoke{
   321  		Session: sid,
   322  		State:   "HALT",
   323  		Stack: []stackitem.Item{
   324  			stackitem.NewInterop(result.Iterator{
   325  				ID: &iid,
   326  				Values: []stackitem.Item{
   327  					stackitem.Make("incorrect format"),
   328  				},
   329  			}),
   330  		},
   331  	}
   332  	ta.err = nil
   333  	iter, err = nns.Roots()
   334  	require.NoError(t, err)
   335  
   336  	_, err = iter.Next(10)
   337  	require.Error(t, err)
   338  	require.Equal(t, "wrong number of elements", err.Error())
   339  
   340  	ta.res = &result.Invoke{
   341  		State: "HALT",
   342  		Stack: []stackitem.Item{
   343  			stackitem.Make([]stackitem.Item{
   344  				stackitem.Make([]stackitem.Item{
   345  					stackitem.Make("root1"),
   346  				}),
   347  				stackitem.Make([]stackitem.Item{
   348  					stackitem.Make("root2"),
   349  				}),
   350  			}),
   351  		},
   352  	}
   353  
   354  	roots, err := nns.RootsExpanded(10)
   355  	require.NoError(t, err)
   356  	require.Equal(t, []string{"root1", "root2"}, roots)
   357  
   358  	ta.res = &result.Invoke{
   359  		State: "HALT",
   360  		Stack: []stackitem.Item{
   361  			stackitem.Make("incorrect format"), // Not a slice of stackitem.Item
   362  		},
   363  	}
   364  
   365  	_, err = nns.RootsExpanded(10)
   366  	require.Error(t, err)
   367  	require.Equal(t, "not an array", err.Error())
   368  
   369  	ta.err = errors.New("call and expand iterator error")
   370  	_, err = nns.RootsExpanded(10)
   371  	require.Error(t, err)
   372  	require.Equal(t, "call and expand iterator error", err.Error())
   373  }
   374  
   375  func TestUpdate(t *testing.T) {
   376  	ta := &testAct{}
   377  	nns := New(ta, util.Uint160{1, 2, 3})
   378  
   379  	nef := []byte{0x01, 0x02, 0x03}
   380  	manifest := "manifest data"
   381  
   382  	ta.err = errors.New("test error")
   383  	_, _, err := nns.Update(nef, manifest)
   384  	require.Error(t, err)
   385  
   386  	// Test successful update
   387  	ta.err = nil
   388  	ta.txh = util.Uint256{0x04, 0x05, 0x06}
   389  	txh, vub, err := nns.Update(nef, manifest)
   390  	require.NoError(t, err)
   391  	require.Equal(t, ta.txh, txh)
   392  	require.Equal(t, ta.vub, vub)
   393  
   394  	for _, fun := range []func(nef []byte, manifest string) (*transaction.Transaction, error){
   395  		nns.UpdateTransaction,
   396  		nns.UpdateUnsigned,
   397  	} {
   398  		ta.err = errors.New("")
   399  		_, err := fun(nil, "")
   400  		require.Error(t, err)
   401  
   402  		ta.err = nil
   403  		ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   404  		tx, err := fun(nil, "")
   405  		require.NoError(t, err)
   406  		require.Equal(t, ta.tx, tx)
   407  	}
   408  }
   409  
   410  func TestAddRoot(t *testing.T) {
   411  	ta := &testAct{}
   412  	nns := New(ta, util.Uint160{1, 2, 3})
   413  
   414  	root := "example.root"
   415  	params, err := smartcontract.NewParameterFromValue(root)
   416  	require.NoError(t, err)
   417  	ta.err = errors.New("test error")
   418  	_, _, err = nns.AddRoot(params.Value.(string))
   419  	require.Error(t, err)
   420  
   421  	// Test success case
   422  	ta.err = nil
   423  	ta.txh = util.Uint256{0x07, 0x08, 0x09}
   424  	txh, vub, err := nns.AddRoot(root)
   425  	require.NoError(t, err)
   426  	require.Equal(t, ta.txh, txh)
   427  	require.Equal(t, ta.vub, vub)
   428  
   429  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   430  	tx, err := nns.AddRootTransaction(root)
   431  	require.NoError(t, err)
   432  	require.Equal(t, ta.tx, tx)
   433  	tx, err = nns.AddRootUnsigned(root)
   434  	require.NoError(t, err)
   435  	require.Equal(t, ta.tx, tx)
   436  
   437  	ta.err = errors.New("")
   438  	_, err = nns.AddRootTransaction(root)
   439  	require.Error(t, err)
   440  
   441  	ta.err = errors.New("")
   442  	_, err = nns.AddRootUnsigned(root)
   443  	require.Error(t, err)
   444  }
   445  
   446  func TestSetPrice(t *testing.T) {
   447  	ta := &testAct{}
   448  	nns := New(ta, util.Uint160{1, 2, 3})
   449  
   450  	priceList := []int64{100, 200}
   451  	ta.err = errors.New("test error")
   452  	_, _, err := nns.SetPrice(priceList)
   453  	require.Error(t, err)
   454  	_, err = nns.SetPriceTransaction(priceList)
   455  	require.Error(t, err)
   456  	_, err = nns.SetPriceUnsigned(priceList)
   457  	require.Error(t, err)
   458  
   459  	// Test success case
   460  	ta.err = nil
   461  	ta.txh = util.Uint256{0x0A, 0x0B, 0x0C}
   462  	ta.vub = 42
   463  
   464  	ta.res = &result.Invoke{
   465  		State: "HALT",
   466  		Stack: []stackitem.Item{
   467  			stackitem.Make(42),
   468  		},
   469  	}
   470  
   471  	txh, vub, err := nns.SetPrice(priceList)
   472  	require.NoError(t, err)
   473  	require.Equal(t, ta.txh, txh)
   474  	require.Equal(t, ta.vub, vub)
   475  
   476  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   477  	tx, err := nns.SetPriceTransaction(priceList)
   478  	require.NoError(t, err)
   479  	require.Equal(t, ta.tx, tx)
   480  	tx, err = nns.SetPriceUnsigned(priceList)
   481  	require.NoError(t, err)
   482  	require.Equal(t, ta.tx, tx)
   483  
   484  	ta.err = errors.New("")
   485  	_, err = nns.SetPriceTransaction(priceList)
   486  	require.Error(t, err)
   487  
   488  	ta.err = errors.New("")
   489  	_, err = nns.SetPriceUnsigned(priceList)
   490  	require.Error(t, err)
   491  }
   492  
   493  func TestRegister(t *testing.T) {
   494  	ta := &testAct{}
   495  	nns := New(ta, util.Uint160{1, 2, 3})
   496  
   497  	name := "example.neo"
   498  	owner := util.Uint160{0x0D, 0x0E, 0x0F}
   499  
   500  	ta.err = errors.New("test error")
   501  	txh, vub, err := nns.Register(name, owner)
   502  	require.Error(t, err)
   503  	require.Equal(t, util.Uint256{}, txh) // Check if returned Uint256 is zero-initialized
   504  	require.Equal(t, uint32(0), vub)
   505  
   506  	// Test success case
   507  	ta.err = nil
   508  	ta.txh = util.Uint256{0x10, 0x11, 0x12}
   509  	txh, vub, err = nns.Register(name, owner)
   510  	require.NoError(t, err)
   511  	require.Equal(t, ta.txh, txh)
   512  	require.Equal(t, ta.vub, vub)
   513  
   514  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   515  	tx, err := nns.RegisterTransaction(name, owner)
   516  	require.NoError(t, err)
   517  	require.Equal(t, ta.tx, tx)
   518  
   519  	tx, err = nns.RegisterUnsigned(name, owner)
   520  	require.NoError(t, err)
   521  	require.Equal(t, ta.tx, tx)
   522  
   523  	ta.err = errors.New("")
   524  	_, err = nns.RegisterTransaction(name, owner)
   525  	require.Error(t, err)
   526  
   527  	ta.err = errors.New("")
   528  	_, err = nns.RegisterUnsigned(name, owner)
   529  	require.Error(t, err)
   530  }
   531  
   532  func TestRenew(t *testing.T) {
   533  	ta := &testAct{}
   534  	nns := New(ta, util.Uint160{1, 2, 3})
   535  
   536  	name := "example.neo"
   537  
   538  	ta.err = errors.New("test error")
   539  	_, _, err := nns.Renew(name)
   540  	require.Error(t, err)
   541  
   542  	// Test success case
   543  	ta.err = nil
   544  	ta.txh = util.Uint256{0x13, 0x14, 0x15}
   545  	txh, vub, err := nns.Renew(name)
   546  	require.NoError(t, err)
   547  	require.Equal(t, ta.txh, txh)
   548  	require.Equal(t, ta.vub, vub)
   549  
   550  	txh, vub, err = nns.Renew2(name, 1)
   551  	require.NoError(t, err)
   552  	require.Equal(t, ta.txh, txh)
   553  	require.Equal(t, ta.vub, vub)
   554  
   555  	ta.tx = &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   556  	tx, err := nns.RenewTransaction(name)
   557  	require.NoError(t, err)
   558  	require.Equal(t, ta.tx, tx)
   559  
   560  	tx, err = nns.RenewUnsigned(name)
   561  	require.NoError(t, err)
   562  	require.Equal(t, ta.tx, tx)
   563  
   564  	ta.err = errors.New("")
   565  	_, err = nns.RenewTransaction(name)
   566  	require.Error(t, err)
   567  
   568  	ta.err = errors.New("")
   569  	_, err = nns.RenewUnsigned(name)
   570  	require.Error(t, err)
   571  }
   572  
   573  func TestSetAdmin(t *testing.T) {
   574  	ta := &testAct{}
   575  	c := New(ta, util.Uint160{1, 2, 3})
   576  
   577  	name := "example.neo"
   578  	admin := util.Uint160{4, 5, 6}
   579  	txMock := &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   580  	txhMock := util.Uint256{0x13, 0x14, 0x15}
   581  
   582  	testCases := []struct {
   583  		name     string
   584  		setup    func()
   585  		testFunc func() (interface{}, error)
   586  		want     interface{}
   587  		wantErr  bool
   588  	}{
   589  		{
   590  			name: "SetAdmin - Error",
   591  			setup: func() {
   592  				ta.err = errors.New("test error")
   593  			},
   594  			testFunc: func() (interface{}, error) {
   595  				txh, vub, err := c.SetAdmin(name, admin)
   596  				return []interface{}{txh, vub}, err
   597  			},
   598  			wantErr: true,
   599  		},
   600  		{
   601  			name: "SetAdmin - Success",
   602  			setup: func() {
   603  				ta.err = nil
   604  				ta.txh = txhMock
   605  				ta.vub = 42
   606  			},
   607  			testFunc: func() (interface{}, error) {
   608  				txh, vub, err := c.SetAdmin(name, admin)
   609  				return []interface{}{txh, vub}, err
   610  			},
   611  			want: []interface{}{txhMock, uint32(42)},
   612  		},
   613  		{
   614  			name: "SetAdminTransaction - Success",
   615  			setup: func() {
   616  				ta.err = nil
   617  				ta.tx = txMock
   618  			},
   619  			testFunc: func() (interface{}, error) {
   620  				return c.SetAdminTransaction(name, admin)
   621  			},
   622  			want: txMock,
   623  		},
   624  		{
   625  			name: "SetAdminTransaction - Error",
   626  			setup: func() {
   627  				ta.err = errors.New("test error")
   628  			},
   629  			testFunc: func() (interface{}, error) {
   630  				return c.SetAdminTransaction(name, admin)
   631  			},
   632  			wantErr: true,
   633  		},
   634  		{
   635  			name: "SetAdminUnsigned - Success",
   636  			setup: func() {
   637  				ta.err = nil
   638  				ta.tx = txMock
   639  			},
   640  			testFunc: func() (interface{}, error) {
   641  				return c.SetAdminUnsigned(name, admin)
   642  			},
   643  			want: txMock,
   644  		},
   645  		{
   646  			name: "SetAdminUnsigned - Error",
   647  			setup: func() {
   648  				ta.err = errors.New("test error")
   649  			},
   650  			testFunc: func() (interface{}, error) {
   651  				return c.SetAdminUnsigned(name, admin)
   652  			},
   653  			wantErr: true,
   654  		},
   655  	}
   656  
   657  	for _, tc := range testCases {
   658  		t.Run(tc.name, func(t *testing.T) {
   659  			tc.setup()
   660  			got, err := tc.testFunc()
   661  			if tc.wantErr {
   662  				require.Error(t, err)
   663  			} else {
   664  				require.NoError(t, err)
   665  				require.Equal(t, tc.want, got)
   666  			}
   667  		})
   668  	}
   669  }
   670  
   671  func TestSetRecord(t *testing.T) {
   672  	ta := &testAct{}
   673  	c := New(ta, util.Uint160{1, 2, 3})
   674  
   675  	name := "example.neo"
   676  	typev := A
   677  	data := "record data"
   678  	txMock := &transaction.Transaction{Nonce: 100500, ValidUntilBlock: 42}
   679  	txhMock := util.Uint256{0x13, 0x14, 0x15}
   680  
   681  	testCases := []struct {
   682  		name     string
   683  		setup    func()
   684  		testFunc func() (interface{}, error)
   685  		want     interface{}
   686  		wantErr  bool
   687  	}{
   688  		{
   689  			name: "SetRecord - Error",
   690  			setup: func() {
   691  				ta.err = errors.New("test error")
   692  			},
   693  			testFunc: func() (interface{}, error) {
   694  				txh, vub, err := c.SetRecord(name, typev, data)
   695  				return []interface{}{txh, vub}, err
   696  			},
   697  			wantErr: true,
   698  		},
   699  		{
   700  			name: "SetRecord - Success",
   701  			setup: func() {
   702  				ta.err = nil
   703  				ta.txh = txhMock
   704  				ta.vub = 42
   705  			},
   706  			testFunc: func() (interface{}, error) {
   707  				txh, vub, err := c.SetRecord(name, typev, data)
   708  				return []interface{}{txh, vub}, err
   709  			},
   710  			want: []interface{}{txhMock, uint32(42)},
   711  		},
   712  		{
   713  			name: "SetRecordTransaction - Success",
   714  			setup: func() {
   715  				ta.err = nil
   716  				ta.tx = txMock
   717  			},
   718  			testFunc: func() (interface{}, error) {
   719  				return c.SetRecordTransaction(name, typev, data)
   720  			},
   721  			want: txMock,
   722  		},
   723  		{
   724  			name: "SetRecordTransaction - Error",
   725  			setup: func() {
   726  				ta.err = errors.New("test error")
   727  			},
   728  			testFunc: func() (interface{}, error) {
   729  				return c.SetRecordTransaction(name, typev, data)
   730  			},
   731  			wantErr: true,
   732  		},
   733  		{
   734  			name: "SetRecordUnsigned - Success",
   735  			setup: func() {
   736  				ta.err = nil
   737  				ta.tx = txMock
   738  			},
   739  			testFunc: func() (interface{}, error) {
   740  				return c.SetRecordUnsigned(name, typev, data)
   741  			},
   742  			want: txMock,
   743  		},
   744  		{
   745  			name: "SetRecordUnsigned - Error",
   746  			setup: func() {
   747  				ta.err = errors.New("test error")
   748  			},
   749  			testFunc: func() (interface{}, error) {
   750  				return c.SetRecordUnsigned(name, typev, data)
   751  			},
   752  			wantErr: true,
   753  		},
   754  	}
   755  
   756  	for _, tc := range testCases {
   757  		t.Run(tc.name, func(t *testing.T) {
   758  			tc.setup()
   759  			got, err := tc.testFunc()
   760  			if tc.wantErr {
   761  				require.Error(t, err)
   762  			} else {
   763  				require.NoError(t, err)
   764  				require.Equal(t, tc.want, got)
   765  			}
   766  		})
   767  	}
   768  }