2020-03-10 13:31:33 +02:00
|
|
|
package internal
|
|
|
|
|
|
|
|
import (
|
2023-05-05 09:49:38 +02:00
|
|
|
"context"
|
2020-03-10 13:31:33 +02:00
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2023-05-05 09:49:38 +02:00
|
|
|
"net/url"
|
2020-03-10 13:31:33 +02:00
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2021-11-02 01:52:38 +02:00
|
|
|
func setupTest(t *testing.T, method, pattern string, status int, file string) *Client {
|
|
|
|
t.Helper()
|
|
|
|
|
2020-03-10 13:31:33 +02:00
|
|
|
mux := http.NewServeMux()
|
|
|
|
server := httptest.NewServer(mux)
|
2021-11-02 01:52:38 +02:00
|
|
|
t.Cleanup(server.Close)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
mux.HandleFunc(pattern, func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != method {
|
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
open, err := os.Open(file)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() { _ = open.Close() }()
|
|
|
|
|
|
|
|
rw.WriteHeader(status)
|
|
|
|
_, err = io.Copy(rw, open)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
client := NewClient()
|
2021-11-02 01:52:38 +02:00
|
|
|
client.HTTPClient = server.Client()
|
2023-05-05 09:49:38 +02:00
|
|
|
client.baseURL, _ = url.Parse(server.URL)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetRootDomain(t *testing.T) {
|
|
|
|
type expected struct {
|
|
|
|
domain *DNSHostname
|
|
|
|
error string
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
pattern string
|
|
|
|
status int
|
|
|
|
file string
|
|
|
|
expected expected
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "success",
|
|
|
|
pattern: "/dns/getroot/test.lego.freeddns.org",
|
|
|
|
status: http.StatusOK,
|
|
|
|
file: "./fixtures/get_root_domain.json",
|
|
|
|
expected: expected{
|
|
|
|
domain: &DNSHostname{
|
|
|
|
APIException: &APIException{
|
|
|
|
StatusCode: 200,
|
|
|
|
},
|
|
|
|
ID: 9007481,
|
|
|
|
DomainName: "lego.freeddns.org",
|
|
|
|
Hostname: "test.lego.freeddns.org",
|
|
|
|
Node: "test",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "invalid",
|
|
|
|
pattern: "/dns/getroot/test.lego.freeddns.org",
|
|
|
|
status: http.StatusNotImplemented,
|
|
|
|
file: "./fixtures/get_root_domain_invalid.json",
|
|
|
|
expected: expected{
|
|
|
|
error: "API error: 501: Argument Exception: Invalid.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2021-11-02 01:52:38 +02:00
|
|
|
client := setupTest(t, http.MethodGet, test.pattern, test.status, test.file)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
domain, err := client.GetRootDomain(context.Background(), "test.lego.freeddns.org")
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
if test.expected.error != "" {
|
|
|
|
assert.EqualError(t, err, test.expected.error)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.NotNil(t, domain)
|
|
|
|
assert.Equal(t, test.expected.domain, domain)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetRecords(t *testing.T) {
|
|
|
|
type expected struct {
|
|
|
|
records []DNSRecord
|
|
|
|
error string
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
pattern string
|
|
|
|
status int
|
|
|
|
file string
|
|
|
|
expected expected
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "success",
|
|
|
|
pattern: "/dns/record/_acme-challenge.lego.freeddns.org",
|
|
|
|
status: http.StatusOK,
|
|
|
|
file: "./fixtures/get_records.json",
|
|
|
|
expected: expected{
|
2020-07-10 01:48:18 +02:00
|
|
|
records: []DNSRecord{
|
|
|
|
{
|
|
|
|
ID: 6041417,
|
|
|
|
Type: "TXT",
|
|
|
|
DomainID: 9007481,
|
|
|
|
DomainName: "lego.freeddns.org",
|
|
|
|
NodeName: "_acme-challenge",
|
|
|
|
Hostname: "_acme-challenge.lego.freeddns.org",
|
|
|
|
State: true,
|
|
|
|
Content: `_acme-challenge.lego.freeddns.org. 300 IN TXT "txt_txt_txt_txt_txt_txt_txt"`,
|
|
|
|
TextData: "txt_txt_txt_txt_txt_txt_txt",
|
|
|
|
TTL: 300,
|
|
|
|
},
|
2020-03-10 13:31:33 +02:00
|
|
|
{
|
|
|
|
ID: 6041422,
|
|
|
|
Type: "TXT",
|
|
|
|
DomainID: 9007481,
|
|
|
|
DomainName: "lego.freeddns.org",
|
|
|
|
NodeName: "_acme-challenge",
|
|
|
|
Hostname: "_acme-challenge.lego.freeddns.org",
|
|
|
|
State: true,
|
|
|
|
Content: `_acme-challenge.lego.freeddns.org. 300 IN TXT "txt_txt_txt_txt_txt_txt_txt_2"`,
|
|
|
|
TextData: "txt_txt_txt_txt_txt_txt_txt_2",
|
|
|
|
TTL: 300,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "empty",
|
|
|
|
pattern: "/dns/record/_acme-challenge.lego.freeddns.org",
|
|
|
|
status: http.StatusOK,
|
|
|
|
file: "./fixtures/get_records_empty.json",
|
|
|
|
expected: expected{
|
|
|
|
records: []DNSRecord{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "invalid",
|
|
|
|
pattern: "/dns/record/_acme-challenge.lego.freeddns.org",
|
|
|
|
status: http.StatusNotImplemented,
|
|
|
|
file: "./fixtures/get_records_invalid.json",
|
|
|
|
expected: expected{
|
|
|
|
error: "API error: 501: Argument Exception: Invalid.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2021-11-02 01:52:38 +02:00
|
|
|
client := setupTest(t, http.MethodGet, test.pattern, test.status, test.file)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
records, err := client.GetRecords(context.Background(), "_acme-challenge.lego.freeddns.org", "TXT")
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
if test.expected.error != "" {
|
|
|
|
assert.EqualError(t, err, test.expected.error)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.NotNil(t, records)
|
|
|
|
assert.Equal(t, test.expected.records, records)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddNewRecord(t *testing.T) {
|
|
|
|
type expected struct {
|
|
|
|
error string
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
pattern string
|
|
|
|
status int
|
|
|
|
file string
|
|
|
|
expected expected
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "success",
|
|
|
|
pattern: "/dns/9007481/record",
|
|
|
|
status: http.StatusOK,
|
|
|
|
file: "./fixtures/add_new_record.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "invalid",
|
|
|
|
pattern: "/dns/9007481/record",
|
|
|
|
status: http.StatusNotImplemented,
|
|
|
|
file: "./fixtures/add_new_record_invalid.json",
|
|
|
|
expected: expected{
|
|
|
|
error: "API error: 501: Argument Exception: Invalid.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2021-11-02 01:52:38 +02:00
|
|
|
client := setupTest(t, http.MethodPost, test.pattern, test.status, test.file)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
record := DNSRecord{
|
|
|
|
Type: "TXT",
|
|
|
|
DomainName: "lego.freeddns.org",
|
|
|
|
Hostname: "_acme-challenge.lego.freeddns.org",
|
|
|
|
NodeName: "_acme-challenge",
|
|
|
|
TextData: "txt_txt_txt_txt_txt_txt_txt_2",
|
|
|
|
State: true,
|
|
|
|
TTL: 300,
|
|
|
|
}
|
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
err := client.AddNewRecord(context.Background(), 9007481, record)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
if test.expected.error != "" {
|
|
|
|
assert.EqualError(t, err, test.expected.error)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteRecord(t *testing.T) {
|
|
|
|
type expected struct {
|
|
|
|
error string
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
pattern string
|
|
|
|
status int
|
|
|
|
file string
|
|
|
|
expected expected
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "success",
|
|
|
|
pattern: "/",
|
|
|
|
status: http.StatusOK,
|
|
|
|
file: "./fixtures/delete_record.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "invalid",
|
|
|
|
pattern: "/",
|
|
|
|
status: http.StatusNotImplemented,
|
|
|
|
file: "./fixtures/delete_record_invalid.json",
|
|
|
|
expected: expected{
|
|
|
|
error: "API error: 501: Argument Exception: Invalid.",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2021-11-02 01:52:38 +02:00
|
|
|
client := setupTest(t, http.MethodDelete, test.pattern, test.status, test.file)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
err := client.DeleteRecord(context.Background(), 9007481, 6041418)
|
2020-03-10 13:31:33 +02:00
|
|
|
|
|
|
|
if test.expected.error != "" {
|
|
|
|
assert.EqualError(t, err, test.expected.error)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|