Files
gluetun/internal/provider/fastestvpn/updater/api_test.go
Quentin McGaw abe9dcbe33 chore(lint): add new linters and update codebase
- add canonicalheader
- add copyloopvar
- add fatcontext
- add intrange
2024-10-11 18:28:00 +00:00

163 lines
4.3 KiB
Go

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 {
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 {
t.Run(name, func(t *testing.T) {
t.Parallel()
nextBlock := getNextBlock([]byte(testCase.data), testCase.startToken, testCase.endToken)
assert.Equal(t, testCase.nextBlock, nextBlock)
})
}
}