github.com/ethersphere/bee/v2@v2.2.0/pkg/api/settlements_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 api_test
     6  
     7  import (
     8  	"errors"
     9  	"math/big"
    10  	"net/http"
    11  	"reflect"
    12  	"testing"
    13  
    14  	"github.com/ethersphere/bee/v2/pkg/api"
    15  	"github.com/ethersphere/bee/v2/pkg/bigint"
    16  	"github.com/ethersphere/bee/v2/pkg/jsonhttp"
    17  	"github.com/ethersphere/bee/v2/pkg/jsonhttp/jsonhttptest"
    18  	"github.com/ethersphere/bee/v2/pkg/settlement"
    19  	"github.com/ethersphere/bee/v2/pkg/settlement/swap/mock"
    20  	"github.com/ethersphere/bee/v2/pkg/swarm"
    21  )
    22  
    23  func TestSettlements(t *testing.T) {
    24  	t.Parallel()
    25  
    26  	settlementsSentFunc := func() (ret map[string]*big.Int, err error) {
    27  		ret = make(map[string]*big.Int)
    28  		ret["DEAD"] = big.NewInt(10000)
    29  		ret["BEEF"] = big.NewInt(20000)
    30  		ret["FFFF"] = big.NewInt(50000)
    31  		return ret, err
    32  	}
    33  
    34  	settlementsRecvFunc := func() (ret map[string]*big.Int, err error) {
    35  		ret = make(map[string]*big.Int)
    36  		ret["BEEF"] = big.NewInt(10000)
    37  		ret["EEEE"] = big.NewInt(5000)
    38  		return ret, err
    39  	}
    40  
    41  	testServer, _, _, _ := newTestServer(t, testServerOptions{
    42  		SwapOpts: []mock.Option{mock.WithSettlementsSentFunc(settlementsSentFunc), mock.WithSettlementsRecvFunc(settlementsRecvFunc)},
    43  	})
    44  
    45  	expected := &api.SettlementsResponse{
    46  		TotalSettlementReceived: bigint.Wrap(big.NewInt(15000)),
    47  		TotalSettlementSent:     bigint.Wrap(big.NewInt(80000)),
    48  		Settlements: []api.SettlementResponse{
    49  			{
    50  				Peer:               "DEAD",
    51  				SettlementReceived: bigint.Wrap(big.NewInt(0)),
    52  				SettlementSent:     bigint.Wrap(big.NewInt(10000)),
    53  			},
    54  			{
    55  				Peer:               "BEEF",
    56  				SettlementReceived: bigint.Wrap(big.NewInt(10000)),
    57  				SettlementSent:     bigint.Wrap(big.NewInt(20000)),
    58  			},
    59  			{
    60  				Peer:               "FFFF",
    61  				SettlementReceived: bigint.Wrap(big.NewInt(0)),
    62  				SettlementSent:     bigint.Wrap(big.NewInt(50000)),
    63  			},
    64  			{
    65  				Peer:               "EEEE",
    66  				SettlementReceived: bigint.Wrap(big.NewInt(5000)),
    67  				SettlementSent:     bigint.Wrap(big.NewInt(0)),
    68  			},
    69  		},
    70  	}
    71  
    72  	// We expect a list of items unordered by peer:
    73  	var got *api.SettlementsResponse
    74  	jsonhttptest.Request(t, testServer, http.MethodGet, "/settlements", http.StatusOK,
    75  		jsonhttptest.WithUnmarshalJSONResponse(&got),
    76  	)
    77  
    78  	if !equalSettlements(got, expected) {
    79  		t.Errorf("got settlements: %+v, expected: %+v", got, expected)
    80  	}
    81  
    82  }
    83  
    84  func TestSettlementsError(t *testing.T) {
    85  	t.Parallel()
    86  
    87  	wantErr := errors.New("New errors")
    88  	settlementsSentFunc := func() (map[string]*big.Int, error) {
    89  		return nil, wantErr
    90  	}
    91  	testServer, _, _, _ := newTestServer(t, testServerOptions{
    92  		SwapOpts: []mock.Option{mock.WithSettlementsSentFunc(settlementsSentFunc)},
    93  	})
    94  
    95  	jsonhttptest.Request(t, testServer, http.MethodGet, "/settlements", http.StatusInternalServerError,
    96  		jsonhttptest.WithExpectedJSONResponse(jsonhttp.StatusResponse{
    97  			Message: api.ErrCantSettlements,
    98  			Code:    http.StatusInternalServerError,
    99  		}),
   100  	)
   101  }
   102  
   103  func TestSettlementsPeers(t *testing.T) {
   104  	t.Parallel()
   105  
   106  	peer := "bff2c89e85e78c38bd89fca1acc996afb876c21bf5a8482ad798ce15f1c223fa"
   107  	settlementSentFunc := func(swarm.Address) (*big.Int, error) {
   108  		return big.NewInt(1000000000000000000), nil
   109  	}
   110  	testServer, _, _, _ := newTestServer(t, testServerOptions{
   111  		SwapOpts: []mock.Option{mock.WithSettlementSentFunc(settlementSentFunc)},
   112  	})
   113  
   114  	jsonhttptest.Request(t, testServer, http.MethodGet, "/settlements/"+peer, http.StatusOK,
   115  		jsonhttptest.WithExpectedJSONResponse(api.SettlementResponse{
   116  			Peer:               peer,
   117  			SettlementSent:     bigint.Wrap(big.NewInt(1000000000000000000)),
   118  			SettlementReceived: bigint.Wrap(big.NewInt(0)),
   119  		}),
   120  	)
   121  }
   122  
   123  func TestSettlementsPeersNoSettlements(t *testing.T) {
   124  	t.Parallel()
   125  
   126  	peer := "bff2c89e85e78c38bd89fca1acc996afb876c21bf5a8482ad798ce15f1c223fa"
   127  	noErrFunc := func(swarm.Address) (*big.Int, error) {
   128  		return big.NewInt(1000000000000000000), nil
   129  	}
   130  	errFunc := func(swarm.Address) (*big.Int, error) {
   131  		return nil, settlement.ErrPeerNoSettlements
   132  	}
   133  
   134  	t.Run("no sent", func(t *testing.T) {
   135  		t.Parallel()
   136  
   137  		testServer, _, _, _ := newTestServer(t, testServerOptions{
   138  			SwapOpts: []mock.Option{
   139  				mock.WithSettlementSentFunc(errFunc),
   140  				mock.WithSettlementRecvFunc(noErrFunc),
   141  			},
   142  		})
   143  
   144  		jsonhttptest.Request(t, testServer, http.MethodGet, "/settlements/"+peer, http.StatusOK,
   145  			jsonhttptest.WithExpectedJSONResponse(api.SettlementResponse{
   146  				Peer:               peer,
   147  				SettlementSent:     bigint.Wrap(big.NewInt(0)),
   148  				SettlementReceived: bigint.Wrap(big.NewInt(1000000000000000000)),
   149  			}),
   150  		)
   151  	})
   152  
   153  	t.Run("no received", func(t *testing.T) {
   154  		t.Parallel()
   155  
   156  		testServer, _, _, _ := newTestServer(t, testServerOptions{
   157  			SwapOpts: []mock.Option{
   158  				mock.WithSettlementSentFunc(noErrFunc),
   159  				mock.WithSettlementRecvFunc(errFunc),
   160  			},
   161  		})
   162  
   163  		jsonhttptest.Request(t, testServer, http.MethodGet, "/settlements/"+peer, http.StatusOK,
   164  			jsonhttptest.WithExpectedJSONResponse(api.SettlementResponse{
   165  				Peer:               peer,
   166  				SettlementSent:     bigint.Wrap(big.NewInt(1000000000000000000)),
   167  				SettlementReceived: bigint.Wrap(big.NewInt(0)),
   168  			}),
   169  		)
   170  	})
   171  }
   172  
   173  func Test_peerSettlementsHandler_invalidInputs(t *testing.T) {
   174  	t.Parallel()
   175  
   176  	client, _, _, _ := newTestServer(t, testServerOptions{})
   177  
   178  	tests := []struct {
   179  		name string
   180  		peer string
   181  		want jsonhttp.StatusResponse
   182  	}{{
   183  		name: "peer - odd hex string",
   184  		peer: "123",
   185  		want: jsonhttp.StatusResponse{
   186  			Code:    http.StatusBadRequest,
   187  			Message: "invalid path params",
   188  			Reasons: []jsonhttp.Reason{
   189  				{
   190  					Field: "peer",
   191  					Error: api.ErrHexLength.Error(),
   192  				},
   193  			},
   194  		},
   195  	}, {
   196  		name: "peer - invalid hex character",
   197  		peer: "123G",
   198  		want: jsonhttp.StatusResponse{
   199  			Code:    http.StatusBadRequest,
   200  			Message: "invalid path params",
   201  			Reasons: []jsonhttp.Reason{
   202  				{
   203  					Field: "peer",
   204  					Error: api.HexInvalidByteError('G').Error(),
   205  				},
   206  			},
   207  		},
   208  	}}
   209  
   210  	for _, tc := range tests {
   211  		tc := tc
   212  		t.Run(tc.name, func(t *testing.T) {
   213  			t.Parallel()
   214  
   215  			jsonhttptest.Request(t, client, http.MethodGet, "/settlements/"+tc.peer, tc.want.Code,
   216  				jsonhttptest.WithExpectedJSONResponse(tc.want),
   217  			)
   218  		})
   219  	}
   220  }
   221  
   222  func TestSettlementsPeersError(t *testing.T) {
   223  	t.Parallel()
   224  
   225  	peer := "bff2c89e85e78c38bd89fca1acc996afb876c21bf5a8482ad798ce15f1c223fa"
   226  	wantErr := errors.New("Error")
   227  	settlementSentFunc := func(swarm.Address) (*big.Int, error) {
   228  		return nil, wantErr
   229  	}
   230  	testServer, _, _, _ := newTestServer(t, testServerOptions{
   231  		SwapOpts: []mock.Option{mock.WithSettlementSentFunc(settlementSentFunc)},
   232  	})
   233  
   234  	jsonhttptest.Request(t, testServer, http.MethodGet, "/settlements/"+peer, http.StatusInternalServerError,
   235  		jsonhttptest.WithExpectedJSONResponse(jsonhttp.StatusResponse{
   236  			Message: api.ErrCantSettlementsPeer,
   237  			Code:    http.StatusInternalServerError,
   238  		}),
   239  	)
   240  }
   241  
   242  func equalSettlements(a, b *api.SettlementsResponse) bool {
   243  	var state bool
   244  
   245  	for akeys := range a.Settlements {
   246  		state = false
   247  		for bkeys := range b.Settlements {
   248  			if reflect.DeepEqual(a.Settlements[akeys], b.Settlements[bkeys]) {
   249  				state = true
   250  				break
   251  			}
   252  		}
   253  		if !state {
   254  			return false
   255  		}
   256  	}
   257  
   258  	for bkeys := range b.Settlements {
   259  		state = false
   260  		for akeys := range a.Settlements {
   261  			if reflect.DeepEqual(a.Settlements[akeys], b.Settlements[bkeys]) {
   262  				state = true
   263  				break
   264  			}
   265  		}
   266  		if !state {
   267  			return false
   268  		}
   269  	}
   270  
   271  	if a.TotalSettlementReceived.Cmp(b.TotalSettlementReceived.Int) != 0 {
   272  		return false
   273  	}
   274  
   275  	if a.TotalSettlementSent.Cmp(b.TotalSettlementSent.Int) != 0 {
   276  		return false
   277  	}
   278  
   279  	return true
   280  }