github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/tequilapi/endpoints/connection_location_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 endpoints
    19  
    20  import (
    21  	"net/http"
    22  	"net/http/httptest"
    23  	"strings"
    24  	"testing"
    25  
    26  	"github.com/gin-gonic/gin"
    27  	"github.com/pkg/errors"
    28  	"github.com/stretchr/testify/assert"
    29  
    30  	"github.com/mysteriumnetwork/go-rest/apierror"
    31  	"github.com/mysteriumnetwork/node/core/ip"
    32  	"github.com/mysteriumnetwork/node/core/location/locationstate"
    33  )
    34  
    35  type locationResolverMock struct {
    36  	ip       string
    37  	ipOrigin string
    38  }
    39  
    40  func (r *locationResolverMock) DetectLocation() (locationstate.Location, error) {
    41  	loc := locationstate.Location{
    42  		ASN:       62179,
    43  		City:      "Vilnius",
    44  		Continent: "EU",
    45  		Country:   "LT",
    46  		IP:        r.ip,
    47  		ISP:       "Telia Lietuva, AB",
    48  		IPType:    "residential",
    49  	}
    50  
    51  	return loc, nil
    52  }
    53  
    54  func (r *locationResolverMock) DetectProxyLocation(_ int) (locationstate.Location, error) {
    55  	return r.DetectLocation()
    56  }
    57  
    58  func (r *locationResolverMock) GetOrigin() locationstate.Location {
    59  	return locationstate.Location{
    60  		ASN:       62179,
    61  		City:      "Vilnius",
    62  		Continent: "EU",
    63  		Country:   "LT",
    64  		IP:        r.ipOrigin,
    65  		ISP:       "Telia Lietuva, AB",
    66  		IPType:    "residential",
    67  	}
    68  }
    69  
    70  func TestAddRoutesForConnectionLocationAddsRoutes(t *testing.T) {
    71  	router := gin.Default()
    72  
    73  	locationResolver := &locationResolverMock{ip: "1.2.3.4", ipOrigin: "1.2.3.1"}
    74  	err := AddRoutesForConnectionLocation(
    75  		ip.NewResolverMock("123.123.123.123"),
    76  		locationResolver,
    77  		locationResolver,
    78  	)(router)
    79  	assert.NoError(t, err)
    80  
    81  	tests := []struct {
    82  		method         string
    83  		path           string
    84  		body           string
    85  		expectedStatus int
    86  		expectedJSON   string
    87  	}{
    88  		{
    89  			http.MethodGet, "/connection/ip", "",
    90  			http.StatusOK, `{"ip": "123.123.123.123"}`,
    91  		},
    92  		{
    93  			http.MethodGet, "/connection/location", "",
    94  			http.StatusOK,
    95  			`{
    96  				"asn": 62179,
    97  				"city": "Vilnius",
    98  				"continent": "EU",
    99  				"country": "LT",
   100  				"region": "",
   101  				"ip": "1.2.3.4",
   102  				"isp": "Telia Lietuva, AB",
   103  				"ip_type": "residential"
   104  			}`,
   105  		},
   106  		{
   107  			http.MethodGet, "/location", "",
   108  			http.StatusOK,
   109  			`{
   110  				"asn": 62179,
   111  				"city": "Vilnius",
   112  				"continent": "EU",
   113  				"country": "LT",
   114  				"region": "",
   115  				"ip": "1.2.3.1",
   116  				"isp": "Telia Lietuva, AB",
   117  				"ip_type": "residential"
   118  			}`,
   119  		},
   120  	}
   121  
   122  	for _, test := range tests {
   123  		resp := httptest.NewRecorder()
   124  		req := httptest.NewRequest(test.method, test.path, strings.NewReader(test.body))
   125  		router.ServeHTTP(resp, req)
   126  		assert.Equal(t, test.expectedStatus, resp.Code)
   127  		if test.expectedJSON != "" {
   128  			assert.JSONEq(t, test.expectedJSON, resp.Body.String())
   129  		} else {
   130  			assert.Equal(t, "", resp.Body.String())
   131  		}
   132  	}
   133  }
   134  
   135  func TestGetIPEndpointSucceeds(t *testing.T) {
   136  	ipResolver := ip.NewResolverMock("123.123.123.123")
   137  
   138  	router := gin.Default()
   139  	err := AddRoutesForConnectionLocation(ipResolver, nil, nil)(router)
   140  	assert.NoError(t, err)
   141  
   142  	resp := httptest.NewRecorder()
   143  	req, err := http.NewRequest(
   144  		http.MethodGet,
   145  		"/connection/ip",
   146  		nil,
   147  	)
   148  	router.ServeHTTP(resp, req)
   149  
   150  	assert.Equal(t, http.StatusOK, resp.Code)
   151  	assert.JSONEq(
   152  		t,
   153  		`{
   154  			"ip": "123.123.123.123"
   155  		}`,
   156  		resp.Body.String(),
   157  	)
   158  }
   159  
   160  func TestGetIPEndpointReturnsErrorWhenIPDetectionFails(t *testing.T) {
   161  	ipResolver := ip.NewResolverMockFailing(errors.New("fake error"))
   162  	router := summonTestGin()
   163  	err := AddRoutesForConnectionLocation(ipResolver, nil, nil)(router)
   164  	assert.NoError(t, err)
   165  	resp := httptest.NewRecorder()
   166  
   167  	req, err := http.NewRequest(
   168  		http.MethodGet,
   169  		"/connection/ip",
   170  		nil,
   171  	)
   172  	router.ServeHTTP(resp, req)
   173  
   174  	assert.Equal(t, http.StatusServiceUnavailable, resp.Code)
   175  	assert.Equal(t, "unavailable", apierror.Parse(resp.Result()).Err.Code)
   176  }