github.com/ethersphere/bee/v2@v2.2.0/pkg/resolver/client/ens/ens_test.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ens_test 6 7 import ( 8 "errors" 9 "testing" 10 11 "github.com/ethereum/go-ethereum/common" 12 "github.com/ethereum/go-ethereum/ethclient" 13 "github.com/ethereum/go-ethereum/rpc" 14 goens "github.com/wealdtech/go-ens/v3" 15 16 "github.com/ethersphere/bee/v2/pkg/resolver" 17 "github.com/ethersphere/bee/v2/pkg/resolver/client/ens" 18 "github.com/ethersphere/bee/v2/pkg/swarm" 19 ) 20 21 func TestNewENSClient(t *testing.T) { 22 t.Parallel() 23 24 testCases := []struct { 25 desc string 26 endpoint string 27 address string 28 connectFn func(string, string) (*ethclient.Client, *goens.Registry, error) 29 wantErr error 30 wantEndpoint string 31 }{ 32 { 33 desc: "nil dial function", 34 endpoint: "someaddress.net", 35 connectFn: nil, 36 wantErr: ens.ErrNotImplemented, 37 }, 38 { 39 desc: "error in dial function", 40 endpoint: "someaddress.com", 41 connectFn: func(s1, s2 string) (*ethclient.Client, *goens.Registry, error) { 42 return nil, nil, errors.New("dial error") 43 }, 44 wantErr: ens.ErrFailedToConnect, 45 }, 46 { 47 desc: "regular endpoint", 48 endpoint: "someaddress.org", 49 connectFn: func(s1, s2 string) (*ethclient.Client, *goens.Registry, error) { 50 return ðclient.Client{}, nil, nil 51 }, 52 wantEndpoint: "someaddress.org", 53 }, 54 } 55 for _, tC := range testCases { 56 tC := tC 57 t.Run(tC.desc, func(t *testing.T) { 58 t.Parallel() 59 60 cl, err := ens.NewClient(tC.endpoint, 61 ens.WithConnectFunc(tC.connectFn), 62 ens.WithContractAddress(tC.address), 63 ) 64 if err != nil { 65 if !errors.Is(err, tC.wantErr) { 66 t.Errorf("got %v, want %v", err, tC.wantErr) 67 } 68 return 69 } 70 if got := cl.Endpoint(); got != tC.wantEndpoint { 71 t.Errorf("endpoint: got %v, want %v", got, tC.wantEndpoint) 72 } 73 if got := cl.IsConnected(); got != true { 74 t.Errorf("connected: got %v, want true", got) 75 } 76 }) 77 } 78 } 79 80 func TestClose(t *testing.T) { 81 t.Parallel() 82 83 t.Run("connected", func(t *testing.T) { 84 t.Parallel() 85 86 rpcServer := rpc.NewServer() 87 defer rpcServer.Stop() 88 ethCl := ethclient.NewClient(rpc.DialInProc(rpcServer)) 89 90 cl, err := ens.NewClient("", 91 ens.WithConnectFunc(func(endpoint, contractAddr string) (*ethclient.Client, *goens.Registry, error) { 92 return ethCl, nil, nil 93 }), 94 ) 95 if err != nil { 96 t.Fatal(err) 97 } 98 99 err = cl.Close() 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 if cl.IsConnected() { 105 t.Error("IsConnected == true") 106 } 107 }) 108 t.Run("not connected", func(t *testing.T) { 109 t.Parallel() 110 111 cl, err := ens.NewClient("", 112 ens.WithConnectFunc(func(endpoint, contractAddr string) (*ethclient.Client, *goens.Registry, error) { 113 return nil, nil, nil 114 }), 115 ) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 err = cl.Close() 121 if err != nil { 122 t.Fatal(err) 123 } 124 125 if cl.IsConnected() { 126 t.Error("IsConnected == true") 127 } 128 }) 129 } 130 131 func TestResolve(t *testing.T) { 132 t.Parallel() 133 134 testContractAddrString := "00000000000C2E074eC69A0dFb2997BA6C702e1B" 135 testContractAddr := common.HexToAddress(testContractAddrString) 136 testSwarmAddr := swarm.MustParseHexAddress("aaabbbcc") 137 138 testCases := []struct { 139 desc string 140 name string 141 contractAddr string 142 resolveFn func(*goens.Registry, common.Address, string) (string, error) 143 wantErr error 144 }{ 145 { 146 desc: "nil resolve function", 147 resolveFn: nil, 148 wantErr: ens.ErrNotImplemented, 149 }, 150 { 151 desc: "resolve function internal error", 152 resolveFn: func(*goens.Registry, common.Address, string) (string, error) { 153 return "", errors.New("internal error") 154 }, 155 wantErr: ens.ErrResolveFailed, 156 }, 157 { 158 desc: "resolver returns empty string", 159 resolveFn: func(*goens.Registry, common.Address, string) (string, error) { 160 return "", nil 161 }, 162 wantErr: resolver.ErrInvalidContentHash, 163 }, 164 { 165 desc: "resolve does not prefix address with /swarm", 166 resolveFn: func(*goens.Registry, common.Address, string) (string, error) { 167 return testSwarmAddr.String(), nil 168 }, 169 wantErr: resolver.ErrInvalidContentHash, 170 }, 171 { 172 desc: "resolve returns prefixed address", 173 resolveFn: func(*goens.Registry, common.Address, string) (string, error) { 174 return ens.SwarmContentHashPrefix + testSwarmAddr.String(), nil 175 }, 176 wantErr: resolver.ErrInvalidContentHash, 177 }, 178 { 179 desc: "expect properly set contract address", 180 resolveFn: func(b *goens.Registry, c common.Address, s string) (string, error) { 181 if c != testContractAddr { 182 return "", errors.New("invalid contract address") 183 } 184 return ens.SwarmContentHashPrefix + testSwarmAddr.String(), nil 185 }, 186 }, 187 } 188 for _, tC := range testCases { 189 tC := tC 190 t.Run(tC.desc, func(t *testing.T) { 191 t.Parallel() 192 193 cl, err := ens.NewClient("example.com", 194 ens.WithContractAddress(testContractAddrString), 195 ens.WithConnectFunc(func(endpoint, contractAddr string) (*ethclient.Client, *goens.Registry, error) { 196 return nil, nil, nil 197 }), 198 ens.WithResolveFunc(tC.resolveFn), 199 ) 200 if err != nil { 201 t.Fatal(err) 202 } 203 _, err = cl.Resolve(tC.name) 204 if err != nil { 205 if !errors.Is(err, tC.wantErr) { 206 t.Errorf("got %v, want %v", err, tC.wantErr) 207 } 208 return 209 } 210 }) 211 } 212 }