github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/cli/smartcontract/smart_contract_test.go (about) 1 package smartcontract 2 3 import ( 4 "flag" 5 "os" 6 "testing" 7 8 "github.com/nspcc-dev/neo-go/internal/random" 9 "github.com/nspcc-dev/neo-go/pkg/crypto/keys" 10 "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" 11 "github.com/stretchr/testify/require" 12 "github.com/urfave/cli" 13 "gopkg.in/yaml.v3" 14 ) 15 16 func TestInitSmartContract(t *testing.T) { 17 d := t.TempDir() 18 testWD, err := os.Getwd() 19 require.NoError(t, err) 20 err = os.Chdir(d) 21 require.NoError(t, err) 22 t.Cleanup(func() { require.NoError(t, os.Chdir(testWD)) }) 23 contractName := "testContract" 24 25 set := flag.NewFlagSet("flagSet", flag.ExitOnError) 26 set.String("name", contractName, "") 27 ctx := cli.NewContext(cli.NewApp(), set, nil) 28 require.NoError(t, initSmartContract(ctx)) 29 dirInfo, err := os.Stat(contractName) 30 require.NoError(t, err) 31 require.True(t, dirInfo.IsDir()) 32 files, err := os.ReadDir(contractName) 33 require.NoError(t, err) 34 require.Equal(t, 3, len(files)) 35 require.Equal(t, "go.mod", files[0].Name()) 36 require.Equal(t, "main.go", files[1].Name()) 37 require.Equal(t, "neo-go.yml", files[2].Name()) 38 main, err := os.ReadFile(contractName + "/" + files[1].Name()) 39 require.NoError(t, err) 40 require.Equal(t, 41 `package `+contractName+` 42 43 import "github.com/nspcc-dev/neo-go/pkg/interop/runtime" 44 45 var notificationName string 46 47 // init initializes notificationName before calling any other smart-contract method 48 func init() { 49 notificationName = "Hello world!" 50 } 51 52 // RuntimeNotify sends runtime notification with "Hello world!" name 53 func RuntimeNotify(args []any) { 54 runtime.Notify(notificationName, args) 55 }`, string(main)) 56 57 manifest, err := os.ReadFile(contractName + "/" + files[2].Name()) 58 require.NoError(t, err) 59 expected := `name: testContract 60 sourceurl: http://example.com/ 61 safemethods: [] 62 supportedstandards: [] 63 events: 64 - name: Hello world! 65 parameters: 66 - name: args 67 type: Array 68 permissions: 69 - methods: '*' 70 ` 71 require.Equal(t, expected, string(manifest)) 72 } 73 74 func testPermissionMarshal(t *testing.T, p *manifest.Permission, expected string) { 75 out, err := yaml.Marshal((*permission)(p)) 76 require.NoError(t, err) 77 require.Equal(t, expected, string(out)) 78 79 t.Run("Unmarshal", func(t *testing.T) { 80 actual := new(permission) 81 require.NoError(t, yaml.Unmarshal(out, actual)) 82 require.Equal(t, p, (*manifest.Permission)(actual)) 83 }) 84 } 85 86 func TestPermissionMarshal(t *testing.T) { 87 t.Run("Wildcard", func(t *testing.T) { 88 p := manifest.NewPermission(manifest.PermissionWildcard) 89 testPermissionMarshal(t, p, "methods: '*'\n") 90 }) 91 t.Run("no allowed methods", func(t *testing.T) { 92 p := manifest.NewPermission(manifest.PermissionWildcard) 93 p.Methods.Restrict() 94 testPermissionMarshal(t, p, "methods: []\n") 95 }) 96 t.Run("hash", func(t *testing.T) { 97 h := random.Uint160() 98 p := manifest.NewPermission(manifest.PermissionHash, h) 99 testPermissionMarshal(t, p, 100 "hash: "+h.StringLE()+"\n"+ 101 "methods: '*'\n") 102 }) 103 t.Run("group with some methods", func(t *testing.T) { 104 priv, err := keys.NewPrivateKey() 105 require.NoError(t, err) 106 107 p := manifest.NewPermission(manifest.PermissionGroup, priv.PublicKey()) 108 p.Methods.Add("abc") 109 p.Methods.Add("lamao") 110 testPermissionMarshal(t, p, 111 "group: "+priv.PublicKey().StringCompressed()+"\n"+ 112 "methods:\n - abc\n - lamao\n") 113 }) 114 } 115 116 func TestPermissionUnmarshalInvalid(t *testing.T) { 117 priv, err := keys.NewPrivateKey() 118 require.NoError(t, err) 119 120 pub := priv.PublicKey().StringCompressed() 121 u160 := random.Uint160().StringLE() 122 testCases := []string{ 123 "hash: []\nmethods: '*'\n", // invalid hash type 124 "hash: notahex\nmethods: '*'\n", // invalid hash 125 "group: []\nmethods: '*'\n", // invalid group type 126 "group: notahex\nmethods: '*'\n", // invalid group 127 "hash: " + u160 + "\n", // missing methods 128 "group: " + pub + "\nhash: " + u160 + "\nmethods: '*'", // hash/group conflict 129 "hash: " + u160 + "\nmethods:\n a: b\n", // invalid methods type 130 "hash: " + u160 + "\nmethods:\n- []\n", // methods array, invalid single 131 } 132 133 for _, tc := range testCases { 134 t.Run(tc, func(t *testing.T) { 135 require.Error(t, yaml.Unmarshal([]byte(tc), new(permission))) 136 }) 137 } 138 }