github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/mobile/mysterium/proposals_manager_test.go (about)

     1  /*
     2   * Copyright (C) 2019 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package mysterium
    19  
    20  import (
    21  	"context"
    22  	"encoding/json"
    23  	"math/big"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/stretchr/testify/assert"
    28  	"github.com/stretchr/testify/suite"
    29  
    30  	"github.com/mysteriumnetwork/node/core/discovery/proposal"
    31  	"github.com/mysteriumnetwork/node/market"
    32  	"github.com/mysteriumnetwork/node/nat"
    33  )
    34  
    35  type proposalManagerTestSuite struct {
    36  	suite.Suite
    37  
    38  	repository       *mockRepository
    39  	proposalsManager *proposalsManager
    40  }
    41  
    42  func (s *proposalManagerTestSuite) SetupTest() {
    43  	s.repository = &mockRepository{}
    44  
    45  	s.proposalsManager = newProposalsManager(
    46  		s.repository,
    47  		nil,
    48  		&mockNATProber{"none", nil},
    49  		60*time.Second,
    50  	)
    51  }
    52  
    53  func (s *proposalManagerTestSuite) TestGetProposalsFromCache() {
    54  	s.proposalsManager.cachedAt = time.Now().Add(1 * time.Hour)
    55  	s.proposalsManager.cache = []proposal.PricedServiceProposal{
    56  		{
    57  			ServiceProposal: market.NewProposal("p1", "openvpn", market.NewProposalOpts{
    58  				Location: &market.Location{
    59  					Country: "US",
    60  					IPType:  "residential",
    61  				},
    62  				Quality: &market.Quality{Quality: 2, Latency: 50, Bandwidth: 10, Uptime: 20},
    63  			}),
    64  			Price: market.Price{
    65  				PricePerHour: big.NewInt(1),
    66  				PricePerGiB:  big.NewInt(2),
    67  			},
    68  		},
    69  	}
    70  
    71  	proposals, err := s.proposalsManager.getProposals(&GetProposalsRequest{
    72  		Refresh:      false,
    73  		PriceHourMax: 0.005,
    74  		PriceGiBMax:  0.7,
    75  	})
    76  	assert.NoError(s.T(), err)
    77  
    78  	bytes, err := json.Marshal(&proposals)
    79  	assert.NoError(s.T(), err)
    80  	assert.JSONEq(s.T(), `{
    81  	  "proposals": [
    82  		{
    83  		  "provider_id": "p1",
    84  		  "service_type": "openvpn",
    85  		  "country": "US",
    86  		  "ip_type": "residential",
    87  		  "quality_level": 3,
    88  		  "price": {
    89  			  "per_gib": 2.0,
    90  			  "per_hour": 1.0,
    91  			  "currency": "MYST"
    92  		  }
    93  		}
    94  	  ]
    95  	}`, string(bytes))
    96  }
    97  
    98  func (s *proposalManagerTestSuite) TestGetProposalsFromAPIWhenNotFoundInCache() {
    99  	s.repository.data = []proposal.PricedServiceProposal{
   100  		{
   101  			ServiceProposal: market.NewProposal("p1", "wireguard", market.NewProposalOpts{
   102  				Location: &market.Location{
   103  					Country: "US",
   104  					IPType:  "residential",
   105  				},
   106  				Quality: &market.Quality{Quality: 2, Latency: 50, Bandwidth: 10, Uptime: 20},
   107  			}),
   108  			Price: market.Price{
   109  				PricePerHour: big.NewInt(1),
   110  				PricePerGiB:  big.NewInt(2),
   111  			},
   112  		},
   113  	}
   114  	proposals, err := s.proposalsManager.getProposals(&GetProposalsRequest{
   115  		Refresh: true,
   116  	})
   117  	assert.NoError(s.T(), err)
   118  
   119  	bytes, err := json.Marshal(&proposals)
   120  	assert.NoError(s.T(), err)
   121  	assert.JSONEq(s.T(), `{
   122  	  "proposals": [
   123  		{
   124  		  "provider_id": "p1",
   125  		  "service_type": "wireguard",
   126  		  "country": "US",
   127  		  "ip_type": "residential",
   128  		  "quality_level": 3,
   129  		  "price": {
   130  			"per_gib": 2.0,
   131  			"per_hour": 1.0,
   132  			"currency": "MYST"
   133  		  }
   134  		}
   135  	  ]
   136  	}`, string(bytes))
   137  }
   138  
   139  func TestProposalManagerSuite(t *testing.T) {
   140  	suite.Run(t, new(proposalManagerTestSuite))
   141  }
   142  
   143  type mockRepository struct {
   144  	data []proposal.PricedServiceProposal
   145  }
   146  
   147  func (m *mockRepository) Proposal(id market.ProposalID) (*proposal.PricedServiceProposal, error) {
   148  	if len(m.data) == 0 {
   149  		return nil, nil
   150  	}
   151  	return &m.data[0], nil
   152  }
   153  
   154  func (m *mockRepository) Proposals(filter *proposal.Filter) ([]proposal.PricedServiceProposal, error) {
   155  	return m.data, nil
   156  }
   157  
   158  func (m *mockRepository) Countries(filter *proposal.Filter) (map[string]int, error) {
   159  	return nil, nil
   160  }
   161  
   162  type mockNATProber struct {
   163  	returnRes nat.NATType
   164  	returnErr error
   165  }
   166  
   167  func (m *mockNATProber) Probe(_ context.Context) (nat.NATType, error) {
   168  	return m.returnRes, m.returnErr
   169  }