package updater import ( "context" "errors" "io" "net/http" "strings" "testing" "github.com/qdm12/gluetun/internal/provider/common" "github.com/stretchr/testify/assert" ) type roundTripFunc func(r *http.Request) (*http.Response, error) func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { return f(r) } func Test_fechAPIServers(t *testing.T) { t.Parallel() errTest := errors.New("test error") testCases := map[string]struct { ctx context.Context protocol string requestBody string responseStatus int responseBody io.ReadCloser transportErr error servers []apiServer errWrapped error errMessage string }{ "transport_error": { ctx: context.Background(), protocol: "tcp", requestBody: "action=vpn_servers&protocol=tcp", responseStatus: http.StatusOK, transportErr: errTest, errWrapped: errTest, errMessage: `sending request: Post ` + `"https://support.fastestvpn.com/wp-admin/admin-ajax.php": ` + `test error`, }, "not_found_status_code": { ctx: context.Background(), protocol: "tcp", requestBody: "action=vpn_servers&protocol=tcp", responseStatus: http.StatusNotFound, errWrapped: common.ErrHTTPStatusCodeNotOK, errMessage: "HTTP status code not OK: 404", }, "empty_data": { ctx: context.Background(), protocol: "tcp", requestBody: "action=vpn_servers&protocol=tcp", responseStatus: http.StatusOK, responseBody: io.NopCloser(strings.NewReader("")), servers: []apiServer{}, }, "single_server": { ctx: context.Background(), protocol: "tcp", requestBody: "action=vpn_servers&protocol=tcp", responseStatus: http.StatusOK, responseBody: io.NopCloser(strings.NewReader( "irrelevantAustraliaSydney" + "au-stream.jumptoserver.comirrelevant")), servers: []apiServer{ {country: "Australia", city: "Sydney", hostname: "au-stream.jumptoserver.com"}, }, }, "two_servers": { ctx: context.Background(), protocol: "tcp", requestBody: "action=vpn_servers&protocol=tcp", responseStatus: http.StatusOK, responseBody: io.NopCloser(strings.NewReader( "AustraliaSydneyau-stream.jumptoserver.com" + "AustraliaSydneyau-01.jumptoserver.com")), servers: []apiServer{ {country: "Australia", city: "Sydney", hostname: "au-stream.jumptoserver.com"}, {country: "Australia", city: "Sydney", hostname: "au-01.jumptoserver.com"}, }, }, } for name, testCase := range testCases { t.Run(name, func(t *testing.T) { t.Parallel() client := &http.Client{ Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) { assert.Equal(t, apiURL, r.URL.String()) requestBody, err := io.ReadAll(r.Body) assert.NoError(t, err) assert.Equal(t, testCase.requestBody, string(requestBody)) if testCase.transportErr != nil { return nil, testCase.transportErr } return &http.Response{ StatusCode: testCase.responseStatus, Body: testCase.responseBody, }, nil }), } entries, err := fetchAPIServers(testCase.ctx, client, testCase.protocol) assert.ErrorIs(t, err, testCase.errWrapped) if testCase.errWrapped != nil { assert.EqualError(t, err, testCase.errMessage) } assert.Equal(t, testCase.servers, entries) }) } } func Test_getNextBlock(t *testing.T) { t.Parallel() testCases := map[string]struct { data string startToken string endToken string nextBlock []byte }{ "empty_data": { startToken: "", endToken: "", }, "start_token_not_found": { data: "test", startToken: "", endToken: "", }, "end_token_not_found": { data: "test", startToken: "", endToken: "", }, "block_found": { data: "xytesttest2zx", startToken: "", endToken: "", nextBlock: []byte("test"), }, } for name, testCase := range testCases { t.Run(name, func(t *testing.T) { t.Parallel() nextBlock := getNextBlock([]byte(testCase.data), testCase.startToken, testCase.endToken) assert.Equal(t, testCase.nextBlock, nextBlock) }) } }