2019-03-11 18:56:48 +02:00
|
|
|
package internal
|
2018-11-02 03:30:09 +02:00
|
|
|
|
|
|
|
import (
|
2023-05-05 09:49:38 +02:00
|
|
|
"bytes"
|
|
|
|
"context"
|
2018-11-02 03:30:09 +02:00
|
|
|
"fmt"
|
2021-08-25 11:44:11 +02:00
|
|
|
"io"
|
2018-11-02 03:30:09 +02:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2023-05-05 09:49:38 +02:00
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2018-11-02 03:30:09 +02:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2020-08-09 16:39:44 +02:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-11-02 03:30:09 +02:00
|
|
|
)
|
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
func setupTest(t *testing.T) (*Client, *http.ServeMux) {
|
2021-11-02 01:52:38 +02:00
|
|
|
t.Helper()
|
|
|
|
|
2018-11-02 03:30:09 +02:00
|
|
|
mux := http.NewServeMux()
|
|
|
|
server := httptest.NewServer(mux)
|
2021-11-02 01:52:38 +02:00
|
|
|
t.Cleanup(server.Close)
|
2018-11-02 03:30:09 +02:00
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
client, err := NewClient("tyo1", "secret")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
client.HTTPClient = server.Client()
|
|
|
|
client.baseURL, _ = url.Parse(server.URL)
|
|
|
|
|
|
|
|
return client, mux
|
|
|
|
}
|
|
|
|
|
|
|
|
func writeFixtureHandler(method, filename string) http.HandlerFunc {
|
|
|
|
return func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != method {
|
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
writeFixture(rw, filename)
|
2018-11-02 03:30:09 +02:00
|
|
|
}
|
2023-05-05 09:49:38 +02:00
|
|
|
}
|
2018-11-02 03:30:09 +02:00
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
func writeBodyHandler(method, content string) http.HandlerFunc {
|
|
|
|
return func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != method {
|
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_, err := fmt.Fprint(rw, content)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func writeFixture(rw http.ResponseWriter, filename string) {
|
|
|
|
file, err := os.Open(filepath.Join("fixtures", filename))
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer func() { _ = file.Close() }()
|
|
|
|
|
|
|
|
_, _ = io.Copy(rw, file)
|
2018-11-02 03:30:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_GetDomainID(t *testing.T) {
|
|
|
|
type expected struct {
|
|
|
|
domainID string
|
|
|
|
error bool
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
domainName string
|
|
|
|
handler http.HandlerFunc
|
|
|
|
expected expected
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "success",
|
|
|
|
domainName: "domain1.com.",
|
2023-05-05 09:49:38 +02:00
|
|
|
handler: writeFixtureHandler(http.MethodGet, "domains_GET.json"),
|
|
|
|
expected: expected{domainID: "09494b72-b65b-4297-9efb-187f65a0553e"},
|
2018-11-02 03:30:09 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "non existing domain",
|
|
|
|
domainName: "domain1.com.",
|
2023-05-05 09:49:38 +02:00
|
|
|
handler: writeBodyHandler(http.MethodGet, "{}"),
|
|
|
|
expected: expected{error: true},
|
2018-11-02 03:30:09 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "marshaling error",
|
|
|
|
domainName: "domain1.com.",
|
2023-05-05 09:49:38 +02:00
|
|
|
handler: writeBodyHandler(http.MethodGet, "[]"),
|
|
|
|
expected: expected{error: true},
|
2018-11-02 03:30:09 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
2023-05-05 09:49:38 +02:00
|
|
|
client, mux := setupTest(t)
|
2018-11-02 03:30:09 +02:00
|
|
|
|
|
|
|
mux.Handle("/v1/domains", test.handler)
|
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
domainID, err := client.GetDomainID(context.Background(), test.domainName)
|
2018-11-02 03:30:09 +02:00
|
|
|
|
|
|
|
if test.expected.error {
|
|
|
|
require.Error(t, err)
|
|
|
|
} else {
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, test.expected.domainID, domainID)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_CreateRecord(t *testing.T) {
|
|
|
|
testCases := []struct {
|
2023-05-05 09:49:38 +02:00
|
|
|
desc string
|
|
|
|
handler http.HandlerFunc
|
|
|
|
assert require.ErrorAssertionFunc
|
2018-11-02 03:30:09 +02:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "success",
|
|
|
|
handler: func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != http.MethodPost {
|
2023-05-05 09:49:38 +02:00
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest)
|
2018-11-02 03:30:09 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-08-25 11:44:11 +02:00
|
|
|
raw, err := io.ReadAll(req.Body)
|
2018-11-02 03:30:09 +02:00
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, err.Error(), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
2023-05-05 09:49:38 +02:00
|
|
|
defer func() { _ = req.Body.Close() }()
|
2018-11-02 03:30:09 +02:00
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
if string(bytes.TrimSpace(raw)) != `{"name":"lego.com.","type":"TXT","data":"txtTXTtxt","ttl":300}` {
|
2018-11-02 03:30:09 +02:00
|
|
|
http.Error(rw, fmt.Sprintf("invalid request body: %s", string(raw)), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
2023-05-05 09:49:38 +02:00
|
|
|
|
|
|
|
writeFixture(rw, "domains-records_POST.json")
|
2018-11-02 03:30:09 +02:00
|
|
|
},
|
2023-05-05 09:49:38 +02:00
|
|
|
assert: require.NoError,
|
2018-11-02 03:30:09 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "bad request",
|
|
|
|
handler: func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != http.MethodPost {
|
2023-05-05 09:49:38 +02:00
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest)
|
2018-11-02 03:30:09 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
http.Error(rw, "OOPS", http.StatusBadRequest)
|
|
|
|
},
|
2023-05-05 09:49:38 +02:00
|
|
|
assert: require.Error,
|
2018-11-02 03:30:09 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
2023-05-05 09:49:38 +02:00
|
|
|
client, mux := setupTest(t)
|
2018-11-02 03:30:09 +02:00
|
|
|
|
|
|
|
mux.Handle("/v1/domains/lego/records", test.handler)
|
|
|
|
|
|
|
|
domainID := "lego"
|
|
|
|
|
|
|
|
record := Record{
|
|
|
|
Name: "lego.com.",
|
|
|
|
Type: "TXT",
|
|
|
|
Data: "txtTXTtxt",
|
|
|
|
TTL: 300,
|
|
|
|
}
|
|
|
|
|
2023-05-05 09:49:38 +02:00
|
|
|
err := client.CreateRecord(context.Background(), domainID, record)
|
|
|
|
test.assert(t, err)
|
2018-11-02 03:30:09 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2023-05-05 09:49:38 +02:00
|
|
|
|
|
|
|
func TestClient_GetRecordID(t *testing.T) {
|
|
|
|
client, mux := setupTest(t)
|
|
|
|
|
|
|
|
mux.HandleFunc("/v1/domains/89acac79-38e7-497d-807c-a011e1310438/records",
|
|
|
|
writeFixtureHandler(http.MethodGet, "domains-records_GET.json"))
|
|
|
|
|
|
|
|
recordID, err := client.GetRecordID(context.Background(), "89acac79-38e7-497d-807c-a011e1310438", "www.example.com.", "A", "15.185.172.153")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, "2e32e609-3a4f-45ba-bdef-e50eacd345ad", recordID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_DeleteRecord(t *testing.T) {
|
|
|
|
client, mux := setupTest(t)
|
|
|
|
|
|
|
|
mux.HandleFunc("/v1/domains/89acac79-38e7-497d-807c-a011e1310438/records/2e32e609-3a4f-45ba-bdef-e50eacd345ad", func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != http.MethodDelete {
|
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
rw.WriteHeader(http.StatusOK)
|
|
|
|
})
|
|
|
|
|
|
|
|
err := client.DeleteRecord(context.Background(), "89acac79-38e7-497d-807c-a011e1310438", "2e32e609-3a4f-45ba-bdef-e50eacd345ad")
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|