lego/providers/dns/joker/internal/dmapi/client_test.go

306 lines
7.2 KiB
Go
Raw Normal View History

2020-10-08 14:52:50 +00:00
package dmapi
2019-04-28 12:33:50 +00:00
import (
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
correctAPIKey = "123"
incorrectAPIKey = "321"
serverErrorAPIKey = "500"
)
const (
correctUsername = "lego"
incorrectUsername = "not_lego"
serverErrorUsername = "error"
2019-04-28 12:33:50 +00:00
)
2023-05-05 07:49:38 +00:00
func setupTest(t *testing.T) (*http.ServeMux, string) {
2020-12-28 22:39:00 +00:00
t.Helper()
2019-04-28 12:33:50 +00:00
mux := http.NewServeMux()
server := httptest.NewServer(mux)
2020-10-08 14:52:50 +00:00
t.Cleanup(server.Close)
return mux, server.URL
2019-04-28 12:33:50 +00:00
}
2023-05-05 07:49:38 +00:00
func TestClient_GetZone(t *testing.T) {
2020-07-09 23:48:18 +00:00
testZone := "@ A 0 192.0.2.2 3600"
2019-04-28 12:33:50 +00:00
testCases := []struct {
desc string
authSid string
domain string
zone string
expectedError bool
expectedStatusCode int
}{
{
desc: "correct auth-sid, known domain",
authSid: correctAPIKey,
2019-04-28 12:33:50 +00:00
domain: "known",
zone: testZone,
expectedStatusCode: 0,
},
{
desc: "incorrect auth-sid, known domain",
authSid: incorrectAPIKey,
2019-04-28 12:33:50 +00:00
domain: "known",
expectedStatusCode: 2202,
},
{
desc: "correct auth-sid, unknown domain",
authSid: correctAPIKey,
2019-04-28 12:33:50 +00:00
domain: "unknown",
expectedStatusCode: 2202,
},
{
desc: "server error",
authSid: "500",
expectedError: true,
},
}
2023-05-05 07:49:38 +00:00
mux, serverURL := setupTest(t)
2019-04-28 12:33:50 +00:00
mux.HandleFunc("/dns-zone-get", func(w http.ResponseWriter, r *http.Request) {
2020-10-08 14:52:50 +00:00
require.Equal(t, http.MethodPost, r.Method)
2019-04-28 12:33:50 +00:00
authSid := r.FormValue("auth-sid")
domain := r.FormValue("domain")
switch {
case authSid == correctAPIKey && domain == "known":
2019-04-28 12:33:50 +00:00
_, _ = io.WriteString(w, "Status-Code: 0\nStatus-Text: OK\n\n"+testZone)
case authSid == incorrectAPIKey || (authSid == correctAPIKey && domain == "unknown"):
2019-04-28 12:33:50 +00:00
_, _ = io.WriteString(w, "Status-Code: 2202\nStatus-Text: Authorization error")
default:
http.NotFound(w, r)
}
})
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
2023-05-05 07:49:38 +00:00
client := NewClient(AuthInfo{APIKey: "12345"})
2020-10-08 14:52:50 +00:00
client.BaseURL = serverURL
2019-04-28 12:33:50 +00:00
2023-05-05 07:49:38 +00:00
response, err := client.GetZone(mockContext(test.authSid), test.domain)
2019-04-28 12:33:50 +00:00
if test.expectedError {
require.Error(t, err)
} else {
require.NoError(t, err)
require.NotNil(t, response)
assert.Equal(t, test.expectedStatusCode, response.StatusCode)
assert.Equal(t, test.zone, response.Body)
}
})
}
}
func Test_parseResponse(t *testing.T) {
testCases := []struct {
desc string
input string
2020-10-08 14:52:50 +00:00
expected *Response
2019-04-28 12:33:50 +00:00
}{
{
desc: "Empty response",
input: "",
2020-10-08 14:52:50 +00:00
expected: &Response{
2019-04-28 12:33:50 +00:00
Headers: url.Values{},
StatusCode: -1,
},
},
{
desc: "No headers, just body",
input: "\n\nTest body",
2020-10-08 14:52:50 +00:00
expected: &Response{
2019-04-28 12:33:50 +00:00
Headers: url.Values{},
Body: "Test body",
StatusCode: -1,
},
},
{
desc: "Headers and body",
input: "Test-Header: value\n\nTest body",
2020-10-08 14:52:50 +00:00
expected: &Response{
2019-04-28 12:33:50 +00:00
Headers: url.Values{"Test-Header": {"value"}},
Body: "Test body",
StatusCode: -1,
},
},
{
desc: "Headers and body + Auth-Sid",
input: "Test-Header: value\nAuth-Sid: 123\n\nTest body",
2020-10-08 14:52:50 +00:00
expected: &Response{
2019-04-28 12:33:50 +00:00
Headers: url.Values{"Test-Header": {"value"}, "Auth-Sid": {"123"}},
Body: "Test body",
StatusCode: -1,
AuthSid: "123",
},
},
{
desc: "Headers and body + Status-Text",
input: "Test-Header: value\nStatus-Text: OK\n\nTest body",
2020-10-08 14:52:50 +00:00
expected: &Response{
2019-04-28 12:33:50 +00:00
Headers: url.Values{"Test-Header": {"value"}, "Status-Text": {"OK"}},
Body: "Test body",
StatusText: "OK",
StatusCode: -1,
},
},
{
desc: "Headers and body + Status-Code",
input: "Test-Header: value\nStatus-Code: 2020\n\nTest body",
2020-10-08 14:52:50 +00:00
expected: &Response{
2019-04-28 12:33:50 +00:00
Headers: url.Values{"Test-Header": {"value"}, "Status-Code": {"2020"}},
Body: "Test body",
StatusCode: 2020,
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
response := parseResponse(test.input)
assert.Equal(t, test.expected, response)
})
}
}
2023-05-05 07:49:38 +00:00
func Test_RemoveTxtEntryFromZone(t *testing.T) {
2019-04-28 12:33:50 +00:00
testCases := []struct {
desc string
input string
expected string
modified bool
}{
{
desc: "empty zone",
input: "",
expected: "",
modified: false,
},
{
desc: "zone with only A entry",
input: "@ A 0 192.0.2.2 3600",
expected: "@ A 0 192.0.2.2 3600",
modified: false,
},
{
desc: "zone with only clenup entry",
input: "_acme-challenge TXT 0 \"old \" 120",
expected: "",
modified: true,
},
{
desc: "zone with one A and one cleanup entries",
input: "@ A 0 192.0.2.2 3600\n_acme-challenge TXT 0 \"old \" 120",
expected: "@ A 0 192.0.2.2 3600",
modified: true,
},
{
desc: "zone with one A and multiple cleanup entries",
input: "@ A 0 192.0.2.2 3600\n_acme-challenge TXT 0 \"old \" 120\n_acme-challenge TXT 0 \"another \" 120",
expected: "@ A 0 192.0.2.2 3600",
modified: true,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
2020-10-08 14:52:50 +00:00
zone, modified := RemoveTxtEntryFromZone(test.input, "_acme-challenge")
2023-10-31 13:08:50 +00:00
assert.Equal(t, test.expected, zone)
assert.Equal(t, test.modified, modified)
2019-04-28 12:33:50 +00:00
})
}
}
2023-05-05 07:49:38 +00:00
func Test_AddTxtEntryToZone(t *testing.T) {
2019-04-28 12:33:50 +00:00
testCases := []struct {
desc string
input string
expected string
}{
{
desc: "empty zone",
input: "",
expected: "_acme-challenge TXT 0 \"test\" 120",
},
{
desc: "zone with A entry",
input: "@ A 0 192.0.2.2 3600",
expected: "@ A 0 192.0.2.2 3600\n_acme-challenge TXT 0 \"test\" 120",
},
{
desc: "zone with required cleanup entry",
input: "_acme-challenge TXT 0 \"old \" 120",
expected: "_acme-challenge TXT 0 \"old\" 120\n_acme-challenge TXT 0 \"test\" 120",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
2020-10-08 14:52:50 +00:00
zone := AddTxtEntryToZone(test.input, "_acme-challenge", "test", 120)
2023-10-31 13:08:50 +00:00
assert.Equal(t, test.expected, zone)
2019-04-28 12:33:50 +00:00
})
}
}
func Test_fixTxtLines(t *testing.T) {
testCases := []struct {
desc string
input string
expected string
}{
{
desc: "clean-up",
input: `_acme-challenge TXT 0 "SrqD25Gpm3WtIGKCqhgsLeXWE_FAD5Hv9CRoLAHxlIE " 120`,
expected: `_acme-challenge TXT 0 "SrqD25Gpm3WtIGKCqhgsLeXWE_FAD5Hv9CRoLAHxlIE" 120`,
},
{
desc: "already cleaned",
input: `_acme-challenge TXT 0 "SrqD25Gpm3WtIGKCqhgsLeXWE_FAD5Hv9CRoLAHxlIE" 120`,
expected: `_acme-challenge TXT 0 "SrqD25Gpm3WtIGKCqhgsLeXWE_FAD5Hv9CRoLAHxlIE" 120`,
},
{
desc: "special DNS entry",
input: "$dyndns=yes:username:password",
expected: "$dyndns=yes:username:password",
},
{
desc: "SRV entry",
input: "_jabber._tcp SRV 20/0 xmpp-server1.l.google.com:5269 300",
expected: "_jabber._tcp SRV 20/0 xmpp-server1.l.google.com:5269 300",
},
{
desc: "MX entry",
input: "@ MX 10 ASPMX.L.GOOGLE.COM 300",
expected: "@ MX 10 ASPMX.L.GOOGLE.COM 300",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
line := fixTxtLines(test.input)
2023-10-31 13:08:50 +00:00
assert.Equal(t, test.expected, line)
2019-04-28 12:33:50 +00:00
})
}
}