feat(fastestvpn): update servers data using API instead of zip file
- Add city filter - More dynamic to servers updates on fastestvpn's end - Update servers data
This commit is contained in:
164
internal/provider/fastestvpn/updater/api_test.go
Normal file
164
internal/provider/fastestvpn/updater/api_test.go
Normal file
@@ -0,0 +1,164 @@
|
||||
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(
|
||||
"irrelevant<tr><td>Australia</td><td>Sydney</td>" +
|
||||
"<td>au-stream.jumptoserver.com</td></tr>irrelevant")),
|
||||
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(
|
||||
"<tr><td>Australia</td><td>Sydney</td><td>au-stream.jumptoserver.com</td></tr>" +
|
||||
"<tr><td>Australia</td><td>Sydney</td><td>au-01.jumptoserver.com</td></tr>")),
|
||||
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 {
|
||||
testCase := testCase
|
||||
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: "<a>",
|
||||
endToken: "</a>",
|
||||
},
|
||||
"start_token_not_found": {
|
||||
data: "test</a>",
|
||||
startToken: "<a>",
|
||||
endToken: "</a>",
|
||||
},
|
||||
"end_token_not_found": {
|
||||
data: "<a>test",
|
||||
startToken: "<a>",
|
||||
endToken: "</a>",
|
||||
},
|
||||
"block_found": {
|
||||
data: "xy<a>test</a><a>test2</a>zx",
|
||||
startToken: "<a>",
|
||||
endToken: "</a>",
|
||||
nextBlock: []byte("<a>test</a>"),
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
nextBlock := getNextBlock([]byte(testCase.data), testCase.startToken, testCase.endToken)
|
||||
|
||||
assert.Equal(t, testCase.nextBlock, nextBlock)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user