ens_test.go 4.97 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ens_test

import (
	"errors"
	"testing"

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 17 18 19
	"github.com/ethersphere/bee/pkg/resolver/client/ens"
	"github.com/ethersphere/bee/pkg/swarm"
)

20 21 22 23
func TestNewENSClient(t *testing.T) {
	testCases := []struct {
		desc         string
		endpoint     string
24 25
		address      string
		connectFn    func(string, string) (*ethclient.Client, *goens.Registry, error)
26 27 28 29
		wantErr      error
		wantEndpoint string
	}{
		{
30 31 32 33
			desc:      "nil dial function",
			endpoint:  "someaddress.net",
			connectFn: nil,
			wantErr:   ens.ErrNotImplemented,
34 35 36 37
		},
		{
			desc:     "error in dial function",
			endpoint: "someaddress.com",
38 39
			connectFn: func(s1, s2 string) (*ethclient.Client, *goens.Registry, error) {
				return nil, nil, errors.New("dial error")
40 41 42 43 44 45
			},
			wantErr: ens.ErrFailedToConnect,
		},
		{
			desc:     "regular endpoint",
			endpoint: "someaddress.org",
46 47
			connectFn: func(s1, s2 string) (*ethclient.Client, *goens.Registry, error) {
				return &ethclient.Client{}, nil, nil
48 49 50 51 52 53 54
			},
			wantEndpoint: "someaddress.org",
		},
	}
	for _, tC := range testCases {
		t.Run(tC.desc, func(t *testing.T) {
			cl, err := ens.NewClient(tC.endpoint,
55 56
				ens.WithConnectFunc(tC.connectFn),
				ens.WithContractAddress(tC.address),
57 58 59 60 61 62 63 64 65 66 67 68 69 70
			)
			if err != nil {
				if !errors.Is(err, tC.wantErr) {
					t.Errorf("got %v, want %v", err, tC.wantErr)
				}
				return
			}
			if got := cl.Endpoint(); got != tC.wantEndpoint {
				t.Errorf("endpoint: got %v, want %v", got, tC.wantEndpoint)
			}
			if got := cl.IsConnected(); got != true {
				t.Errorf("connected: got %v, want true", got)
			}
		})
71 72 73
	}
}

74 75 76 77 78
func TestClose(t *testing.T) {
	t.Run("connected", func(t *testing.T) {
		rpcServer := rpc.NewServer()
		defer rpcServer.Stop()
		ethCl := ethclient.NewClient(rpc.DialInProc(rpcServer))
79

80
		cl, err := ens.NewClient("",
81 82
			ens.WithConnectFunc(func(endpoint, contractAddr string) (*ethclient.Client, *goens.Registry, error) {
				return ethCl, nil, nil
83
			}),
84
		)
85
		if err != nil {
86 87 88
			t.Fatal(err)
		}

89 90
		err = cl.Close()
		if err != nil {
91 92 93
			t.Fatal(err)
		}

94 95
		if cl.IsConnected() {
			t.Error("IsConnected == true")
96 97
		}
	})
98 99
	t.Run("not connected", func(t *testing.T) {
		cl, err := ens.NewClient("",
100 101
			ens.WithConnectFunc(func(endpoint, contractAddr string) (*ethclient.Client, *goens.Registry, error) {
				return nil, nil, nil
102
			}),
103
		)
104
		if err != nil {
105 106 107
			t.Fatal(err)
		}

108 109
		err = cl.Close()
		if err != nil {
110 111 112
			t.Fatal(err)
		}

113 114
		if cl.IsConnected() {
			t.Error("IsConnected == true")
115 116
		}
	})
117
}
118

119
func TestResolve(t *testing.T) {
120 121 122
	testContractAddrString := "00000000000C2E074eC69A0dFb2997BA6C702e1B"
	testContractAddr := common.HexToAddress(testContractAddrString)
	testSwarmAddr := swarm.MustParseHexAddress("aaabbbcc")
123 124

	testCases := []struct {
125 126 127 128 129
		desc         string
		name         string
		contractAddr string
		resolveFn    func(*goens.Registry, common.Address, string) (string, error)
		wantErr      error
130 131 132 133 134 135 136 137
	}{
		{
			desc:      "nil resolve function",
			resolveFn: nil,
			wantErr:   ens.ErrNotImplemented,
		},
		{
			desc: "resolve function internal error",
138
			resolveFn: func(*goens.Registry, common.Address, string) (string, error) {
139 140 141 142 143 144
				return "", errors.New("internal error")
			},
			wantErr: ens.ErrResolveFailed,
		},
		{
			desc: "resolver returns empty string",
145
			resolveFn: func(*goens.Registry, common.Address, string) (string, error) {
146 147 148 149 150 151
				return "", nil
			},
			wantErr: ens.ErrInvalidContentHash,
		},
		{
			desc: "resolve does not prefix address with /swarm",
152 153
			resolveFn: func(*goens.Registry, common.Address, string) (string, error) {
				return testSwarmAddr.String(), nil
154 155 156 157 158
			},
			wantErr: ens.ErrInvalidContentHash,
		},
		{
			desc: "resolve returns prefixed address",
159 160
			resolveFn: func(*goens.Registry, common.Address, string) (string, error) {
				return ens.SwarmContentHashPrefix + testSwarmAddr.String(), nil
161 162 163
			},
			wantErr: ens.ErrInvalidContentHash,
		},
164 165 166 167 168 169 170 171 172
		{
			desc: "expect properly set contract address",
			resolveFn: func(b *goens.Registry, c common.Address, s string) (string, error) {
				if c != testContractAddr {
					return "", errors.New("invalid contract address")
				}
				return ens.SwarmContentHashPrefix + testSwarmAddr.String(), nil
			},
		},
173 174 175 176
	}
	for _, tC := range testCases {
		t.Run(tC.desc, func(t *testing.T) {
			cl, err := ens.NewClient("example.com",
177 178 179
				ens.WithContractAddress(testContractAddrString),
				ens.WithConnectFunc(func(endpoint, contractAddr string) (*ethclient.Client, *goens.Registry, error) {
					return nil, nil, nil
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
				}),
				ens.WithResolveFunc(tC.resolveFn),
			)
			if err != nil {
				t.Fatal(err)
			}
			_, err = cl.Resolve(tC.name)
			if err != nil {
				if !errors.Is(err, tC.wantErr) {
					t.Errorf("got %v, want %v", err, tC.wantErr)
				}
				return
			}
		})
	}
195
}