lego/providers/dns/loopia/internal/client_test.go

338 lines
7.5 KiB
Go
Raw Normal View History

2020-12-26 16:22:01 +00:00
package internal
import (
2023-05-05 07:49:38 +00:00
"context"
2020-12-26 16:22:01 +00:00
"encoding/xml"
"fmt"
2021-08-25 09:44:11 +00:00
"io"
2020-12-26 16:22:01 +00:00
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestClient_AddZoneRecord(t *testing.T) {
serverResponses := map[string]string{
addZoneRecordGoodAuth: responseOk,
addZoneRecordBadAuth: responseAuthError,
addZoneRecordNonValidDomain: responseUnknownError,
addZoneRecordEmptyResponse: "",
}
2020-12-28 22:39:00 +00:00
serverURL := createFakeServer(t, serverResponses)
2020-12-26 16:22:01 +00:00
testCases := []struct {
desc string
password string
domain string
err string
}{
{
desc: "auth ok",
password: "goodpassword",
domain: exampleDomain,
},
{
desc: "auth error",
password: "badpassword",
domain: exampleDomain,
err: "authentication error",
},
{
desc: "unknown error",
password: "goodpassword",
domain: "badexample.com",
err: `unknown error: "UNKNOWN_ERROR"`,
},
{
desc: "empty response",
password: "goodpassword",
domain: "empty.com",
2023-05-05 07:49:38 +00:00
err: "unmarshal error: EOF",
2020-12-26 16:22:01 +00:00
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
client := NewClient("apiuser", test.password)
2020-12-28 22:39:00 +00:00
client.BaseURL = serverURL + "/"
2020-12-26 16:22:01 +00:00
2023-05-05 07:49:38 +00:00
err := client.AddTXTRecord(context.Background(), test.domain, exampleSubDomain, 123, "TXTrecord")
2021-03-04 19:16:59 +00:00
if test.err == "" {
2020-12-26 16:22:01 +00:00
require.NoError(t, err)
} else {
require.Error(t, err)
assert.EqualError(t, err, test.err)
}
})
}
}
func TestClient_RemoveSubdomain(t *testing.T) {
serverResponses := map[string]string{
removeSubdomainGoodAuth: responseOk,
removeSubdomainBadAuth: responseAuthError,
removeSubdomainNonValidDomain: responseUnknownError,
removeSubdomainEmptyResponse: "",
}
2020-12-28 22:39:00 +00:00
serverURL := createFakeServer(t, serverResponses)
2020-12-26 16:22:01 +00:00
testCases := []struct {
desc string
password string
domain string
err string
}{
{
desc: "auth ok",
password: "goodpassword",
domain: exampleDomain,
},
{
desc: "auth error",
password: "badpassword",
domain: exampleDomain,
err: "authentication error",
},
{
desc: "unknown error",
password: "goodpassword",
domain: "badexample.com",
err: `unknown error: "UNKNOWN_ERROR"`,
},
{
desc: "empty response",
password: "goodpassword",
domain: "empty.com",
2023-05-05 07:49:38 +00:00
err: "unmarshal error: EOF",
2020-12-26 16:22:01 +00:00
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
client := NewClient("apiuser", test.password)
2020-12-28 22:39:00 +00:00
client.BaseURL = serverURL + "/"
2020-12-26 16:22:01 +00:00
2023-05-05 07:49:38 +00:00
err := client.RemoveSubdomain(context.Background(), test.domain, exampleSubDomain)
2021-03-04 19:16:59 +00:00
if test.err == "" {
2020-12-26 16:22:01 +00:00
require.NoError(t, err)
} else {
require.Error(t, err)
assert.EqualError(t, err, test.err)
}
})
}
}
func TestClient_RemoveZoneRecord(t *testing.T) {
serverResponses := map[string]string{
removeRecordGoodAuth: responseOk,
removeRecordBadAuth: responseAuthError,
removeRecordNonValidDomain: responseUnknownError,
removeRecordEmptyResponse: "",
}
2020-12-28 22:39:00 +00:00
serverURL := createFakeServer(t, serverResponses)
2020-12-26 16:22:01 +00:00
testCases := []struct {
desc string
password string
domain string
err string
}{
{
desc: "auth ok",
password: "goodpassword",
domain: exampleDomain,
},
{
desc: "auth error",
password: "badpassword",
domain: exampleDomain,
err: "authentication error",
},
{
desc: "uknown error",
password: "goodpassword",
domain: "badexample.com",
err: `unknown error: "UNKNOWN_ERROR"`,
},
{
desc: "empty response",
password: "goodpassword",
domain: "empty.com",
2023-05-05 07:49:38 +00:00
err: "unmarshal error: EOF",
2020-12-26 16:22:01 +00:00
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
client := NewClient("apiuser", test.password)
2020-12-28 22:39:00 +00:00
client.BaseURL = serverURL + "/"
2020-12-26 16:22:01 +00:00
2023-05-05 07:49:38 +00:00
err := client.RemoveTXTRecord(context.Background(), test.domain, exampleSubDomain, 12345678)
2021-03-04 19:16:59 +00:00
if test.err == "" {
2020-12-26 16:22:01 +00:00
require.NoError(t, err)
} else {
require.Error(t, err)
assert.EqualError(t, err, test.err)
}
})
}
}
func TestClient_GetZoneRecord(t *testing.T) {
serverResponses := map[string]string{
getZoneRecords: getZoneRecordsResponse,
}
2020-12-28 22:39:00 +00:00
serverURL := createFakeServer(t, serverResponses)
2020-12-26 16:22:01 +00:00
client := NewClient("apiuser", "goodpassword")
2020-12-28 22:39:00 +00:00
client.BaseURL = serverURL + "/"
2020-12-26 16:22:01 +00:00
2023-05-05 07:49:38 +00:00
recordObjs, err := client.GetTXTRecords(context.Background(), exampleDomain, exampleSubDomain)
2020-12-26 16:22:01 +00:00
require.NoError(t, err)
expected := []RecordObj{
{
Type: "TXT",
TTL: 300,
Priority: 0,
Rdata: exampleRdata,
RecordID: 12345678,
},
}
assert.EqualValues(t, expected, recordObjs)
}
func TestClient_rpcCall_404(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2021-08-25 09:44:11 +00:00
_, err := io.ReadAll(r.Body)
2020-12-26 16:22:01 +00:00
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusNotFound)
_, err = fmt.Fprint(w, "<?xml version='1.0' encoding='UTF-8'?>")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}))
t.Cleanup(server.Close)
call := &methodCall{
MethodName: "dummyMethod",
Params: []param{
paramString{Value: "test1"},
},
}
client := NewClient("apiuser", "apipassword")
client.BaseURL = server.URL + "/"
2023-05-05 07:49:38 +00:00
err := client.rpcCall(context.Background(), call, &responseString{})
assert.EqualError(t, err, "unexpected status code: [status code: 404] body: <?xml version='1.0' encoding='UTF-8'?>")
2020-12-26 16:22:01 +00:00
}
func TestClient_rpcCall_RPCError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2021-08-25 09:44:11 +00:00
_, err := io.ReadAll(r.Body)
2020-12-26 16:22:01 +00:00
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
_, err = fmt.Fprint(w, responseRPCError)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}))
t.Cleanup(server.Close)
call := &methodCall{
MethodName: "getDomains",
Params: []param{
paramString{Value: "test1"},
},
}
client := NewClient("apiuser", "apipassword")
client.BaseURL = server.URL + "/"
2023-05-05 07:49:38 +00:00
err := client.rpcCall(context.Background(), call, &responseString{})
2020-12-26 16:22:01 +00:00
assert.EqualError(t, err, "RPC Error: (201) Method signature error: 42")
}
func TestUnmarshallFaultyRecordObject(t *testing.T) {
testCases := []struct {
desc string
xml string
}{
{
desc: "faulty name",
xml: "<name>name<name>",
},
{
desc: "faulty string",
xml: "<value><string>foo<string></value>",
},
{
desc: "faulty int",
xml: "<value><int>1<int></value>",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
resp := &RecordObj{}
err := xml.Unmarshal([]byte(test.xml), resp)
require.Error(t, err)
})
}
}
2020-12-28 22:39:00 +00:00
func createFakeServer(t *testing.T, serverResponses map[string]string) string {
t.Helper()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2020-12-26 16:22:01 +00:00
if r.Header.Get("Content-Type") != "text/xml" {
http.Error(w, fmt.Sprintf("invalid content type: %s", r.Header.Get("Content-Type")), http.StatusBadRequest)
return
}
2021-08-25 09:44:11 +00:00
req, err := io.ReadAll(r.Body)
2020-12-26 16:22:01 +00:00
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
resp, ok := serverResponses[string(req)]
if !ok {
http.Error(w, "no response for request", http.StatusBadRequest)
return
}
_, err = fmt.Fprint(w, resp)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
2020-12-26 16:22:01 +00:00
server := httptest.NewServer(handler)
2020-12-26 16:22:01 +00:00
t.Cleanup(server.Close)
2020-12-28 22:39:00 +00:00
return server.URL
2020-12-26 16:22:01 +00:00
}