Skip to content

Commit 53d46d3

Browse files
committed
tests: add more tests
1 parent 624ac72 commit 53d46d3

File tree

7 files changed

+168
-21
lines changed

7 files changed

+168
-21
lines changed

providers/dns/allinkl/allinkl_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
package allinkl
22

33
import (
4+
"encoding/json"
5+
"encoding/xml"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
"net/http/httptest"
10+
"net/url"
411
"testing"
512

613
"github.com/go-acme/lego/v4/platform/tester"
14+
"github.com/go-acme/lego/v4/platform/tester/servermock"
15+
"github.com/go-acme/lego/v4/providers/dns/allinkl/internal"
716
"github.com/stretchr/testify/require"
817
)
918

@@ -143,3 +152,108 @@ func TestLiveCleanUp(t *testing.T) {
143152
err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
144153
require.NoError(t, err)
145154
}
155+
156+
func mockBuilder() *servermock.Builder[*DNSProvider] {
157+
return servermock.NewBuilder(
158+
func(server *httptest.Server) (*DNSProvider, error) {
159+
config := NewDefaultConfig()
160+
config.Login = "user"
161+
config.Password = "secret"
162+
config.HTTPClient = server.Client()
163+
164+
p, err := NewDNSProviderConfig(config)
165+
if err != nil {
166+
return nil, err
167+
}
168+
169+
p.client.BaseURL, _ = url.Parse(server.URL)
170+
p.identifier.BaseURL, _ = url.Parse(server.URL)
171+
172+
return p, err
173+
},
174+
).Route("POST /KasAuth.php",
175+
servermock.ResponseFromInternal("auth.xml"),
176+
servermock.CheckRequestBodyFromInternal("auth-request.xml").
177+
IgnoreWhitespace(),
178+
)
179+
}
180+
181+
func extractKasRequest(reader io.Reader) (*internal.KasRequest, error) {
182+
type ReqEnvelope struct {
183+
XMLName xml.Name `xml:"Envelope"`
184+
Body struct {
185+
KasAPI struct {
186+
Params string `xml:"Params"`
187+
} `xml:"KasApi"`
188+
} `xml:"Body"`
189+
}
190+
191+
raw, err := io.ReadAll(reader)
192+
if err != nil {
193+
return nil, err
194+
}
195+
196+
reqEnvelope := ReqEnvelope{}
197+
198+
err = xml.Unmarshal(raw, &reqEnvelope)
199+
if err != nil {
200+
return nil, err
201+
}
202+
203+
var kReq internal.KasRequest
204+
205+
err = json.Unmarshal([]byte(reqEnvelope.Body.KasAPI.Params), &kReq)
206+
if err != nil {
207+
return nil, err
208+
}
209+
210+
return &kReq, nil
211+
}
212+
213+
func TestDNSProvider_Present(t *testing.T) {
214+
provider := mockBuilder().
215+
Route("POST /KasApi.php",
216+
http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
217+
kReq, err := extractKasRequest(req.Body)
218+
if err != nil {
219+
http.Error(rw, err.Error(), http.StatusBadRequest)
220+
return
221+
}
222+
223+
switch kReq.Action {
224+
case "get_dns_settings":
225+
params := kReq.RequestParams.(map[string]any)
226+
227+
if params["zone_host"] == "_acme-challenge.example.com" {
228+
servermock.ResponseFromInternal("get_dns_settings_not_found.xml").ServeHTTP(rw, req)
229+
} else {
230+
servermock.ResponseFromInternal("get_dns_settings.xml").ServeHTTP(rw, req)
231+
}
232+
233+
case "add_dns_settings":
234+
servermock.ResponseFromInternal("add_dns_settings.xml").ServeHTTP(rw, req)
235+
236+
default:
237+
http.Error(rw, fmt.Sprintf("unknown action: %v", kReq.Action), http.StatusBadRequest)
238+
}
239+
}),
240+
).
241+
Build(t)
242+
243+
err := provider.Present("example.com", "abc", "123d==")
244+
require.NoError(t, err)
245+
}
246+
247+
func TestDNSProvider_CleanUp(t *testing.T) {
248+
provider := mockBuilder().
249+
Route("POST /KasApi.php",
250+
servermock.ResponseFromInternal("delete_dns_settings.xml"),
251+
servermock.CheckRequestBodyFromInternal("delete_dns_settings-request.xml").
252+
IgnoreWhitespace()).
253+
Build(t)
254+
255+
provider.recordIDs["abc"] = "57347450"
256+
257+
err := provider.CleanUp("example.com", "abc", "123d==")
258+
require.NoError(t, err)
259+
}

providers/dns/allinkl/internal/client.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"fmt"
88
"net/http"
9+
"net/url"
910
"strconv"
1011
"strings"
1112
"sync"
@@ -15,7 +16,9 @@ import (
1516
"github.com/go-viper/mapstructure/v2"
1617
)
1718

18-
const apiEndpoint = "https://kasapi.kasserver.com/soap/KasApi.php"
19+
const defaultBaseURL = "https://kasapi.kasserver.com/soap/"
20+
21+
const apiPath = "KasApi.php"
1922

2023
type Authentication interface {
2124
Authentication(ctx context.Context, sessionLifetime int, sessionUpdateLifetime bool) (string, error)
@@ -28,15 +31,17 @@ type Client struct {
2831
floodTime time.Time
2932
muFloodTime sync.Mutex
3033

31-
baseURL string
34+
BaseURL *url.URL
3235
HTTPClient *http.Client
3336
}
3437

3538
// NewClient creates a new Client.
3639
func NewClient(login string) *Client {
40+
baseURL, _ := url.Parse(defaultBaseURL)
41+
3742
return &Client{
3843
login: login,
39-
baseURL: apiEndpoint,
44+
BaseURL: baseURL,
4045
HTTPClient: &http.Client{Timeout: 10 * time.Second},
4146
}
4247
}
@@ -124,7 +129,9 @@ func (c *Client) newRequest(ctx context.Context, action string, requestParams an
124129

125130
payload := []byte(strings.TrimSpace(fmt.Sprintf(kasAPIEnvelope, body)))
126131

127-
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL, bytes.NewReader(payload))
132+
endpoint := c.BaseURL.JoinPath(apiPath)
133+
134+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), bytes.NewReader(payload))
128135
if err != nil {
129136
return nil, fmt.Errorf("unable to create request: %w", err)
130137
}

providers/dns/allinkl/internal/client_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package internal
22

33
import (
44
"net/http/httptest"
5+
"net/url"
56
"testing"
67

78
"github.com/go-acme/lego/v4/platform/tester/servermock"
@@ -11,15 +12,15 @@ import (
1112

1213
func setupClient(server *httptest.Server) (*Client, error) {
1314
client := NewClient("user")
14-
client.baseURL = server.URL
15+
client.BaseURL, _ = url.Parse(server.URL)
1516
client.HTTPClient = server.Client()
1617

1718
return client, nil
1819
}
1920

2021
func TestClient_GetDNSSettings(t *testing.T) {
2122
client := servermock.NewBuilder[*Client](setupClient).
22-
Route("POST /", servermock.ResponseFromFixture("get_dns_settings.xml"),
23+
Route("POST /KasApi.php", servermock.ResponseFromFixture("get_dns_settings.xml"),
2324
servermock.CheckRequestBodyFromFixture("get_dns_settings-request.xml").
2425
IgnoreWhitespace()).
2526
Build(t)
@@ -98,7 +99,7 @@ func TestClient_GetDNSSettings(t *testing.T) {
9899

99100
func TestClient_AddDNSSettings(t *testing.T) {
100101
client := servermock.NewBuilder[*Client](setupClient).
101-
Route("POST /", servermock.ResponseFromFixture("add_dns_settings.xml"),
102+
Route("POST /KasApi.php", servermock.ResponseFromFixture("add_dns_settings.xml"),
102103
servermock.CheckRequestBodyFromFixture("add_dns_settings-request.xml").
103104
IgnoreWhitespace()).
104105
Build(t)
@@ -118,7 +119,7 @@ func TestClient_AddDNSSettings(t *testing.T) {
118119

119120
func TestClient_DeleteDNSSettings(t *testing.T) {
120121
client := servermock.NewBuilder[*Client](setupClient).
121-
Route("POST /", servermock.ResponseFromFixture("delete_dns_settings.xml"),
122+
Route("POST /KasApi.php", servermock.ResponseFromFixture("delete_dns_settings.xml"),
122123
servermock.CheckRequestBodyFromFixture("delete_dns_settings-request.xml").
123124
IgnoreWhitespace()).
124125
Build(t)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
2+
<Body>
3+
<KasAuth xmlns="https://kasserver.com/">
4+
<Params>{"kas_login":"user","kas_auth_data":"secret","kas_auth_type":"plain","session_lifetime":60,"session_update_lifetime":"Y"}</Params>
5+
</KasAuth>
6+
</Body>
7+
</Envelope>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
3+
<SOAP-ENV:Body>
4+
<SOAP-ENV:Fault>
5+
<faultcode>SOAP-ENV:Server</faultcode>
6+
<faultstring>zone_not_found</faultstring>
7+
<faultactor>KasApi</faultactor>
8+
</SOAP-ENV:Fault>
9+
</SOAP-ENV:Body>
10+
</SOAP-ENV:Envelope>

providers/dns/allinkl/internal/identity.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import (
66
"encoding/json"
77
"fmt"
88
"net/http"
9+
"net/url"
910
"strings"
1011
"time"
1112

1213
"github.com/go-acme/lego/v4/providers/dns/internal/errutils"
1314
)
1415

15-
// authEndpoint represents the Identity API endpoint to call.
16-
const authEndpoint = "https://kasapi.kasserver.com/soap/KasAuth.php"
16+
const authPath = "KasAuth.php"
1717

1818
type token string
1919

@@ -24,17 +24,19 @@ type Identifier struct {
2424
login string
2525
password string
2626

27-
authEndpoint string
28-
HTTPClient *http.Client
27+
BaseURL *url.URL
28+
HTTPClient *http.Client
2929
}
3030

3131
// NewIdentifier creates a new Identifier.
3232
func NewIdentifier(login, password string) *Identifier {
33+
baseURL, _ := url.Parse(defaultBaseURL)
34+
3335
return &Identifier{
34-
login: login,
35-
password: password,
36-
authEndpoint: authEndpoint,
37-
HTTPClient: &http.Client{Timeout: 10 * time.Second},
36+
login: login,
37+
password: password,
38+
BaseURL: baseURL,
39+
HTTPClient: &http.Client{Timeout: 10 * time.Second},
3840
}
3941
}
4042

@@ -62,7 +64,9 @@ func (c *Identifier) Authentication(ctx context.Context, sessionLifetime int, se
6264

6365
payload := []byte(strings.TrimSpace(fmt.Sprintf(kasAuthEnvelope, body)))
6466

65-
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.authEndpoint, bytes.NewReader(payload))
67+
endpoint := c.BaseURL.JoinPath(authPath)
68+
69+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), bytes.NewReader(payload))
6670
if err != nil {
6771
return "", fmt.Errorf("unable to create request: %w", err)
6872
}

providers/dns/allinkl/internal/identity_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package internal
33
import (
44
"context"
55
"net/http/httptest"
6+
"net/url"
67
"testing"
78

89
"github.com/go-acme/lego/v4/platform/tester/servermock"
@@ -12,7 +13,7 @@ import (
1213

1314
func setupIdentifierClient(server *httptest.Server) (*Identifier, error) {
1415
client := NewIdentifier("user", "secret")
15-
client.authEndpoint = server.URL
16+
client.BaseURL, _ = url.Parse(server.URL)
1617
client.HTTPClient = server.Client()
1718

1819
return client, nil
@@ -26,18 +27,21 @@ func mockContext(t *testing.T) context.Context {
2627

2728
func TestIdentifier_Authentication(t *testing.T) {
2829
client := servermock.NewBuilder[*Identifier](setupIdentifierClient).
29-
Route("POST /", servermock.ResponseFromFixture("auth.xml")).
30+
Route("POST /KasAuth.php",
31+
servermock.ResponseFromFixture("auth.xml"),
32+
servermock.CheckRequestBodyFromFixture("auth-request.xml").
33+
IgnoreWhitespace()).
3034
Build(t)
3135

32-
credentialToken, err := client.Authentication(t.Context(), 60, false)
36+
credentialToken, err := client.Authentication(t.Context(), 60, true)
3337
require.NoError(t, err)
3438

3539
assert.Equal(t, "593959ca04f0de9689b586c6a647d15d", credentialToken)
3640
}
3741

3842
func TestIdentifier_Authentication_error(t *testing.T) {
3943
client := servermock.NewBuilder[*Identifier](setupIdentifierClient).
40-
Route("POST /", servermock.ResponseFromFixture("auth_fault.xml")).
44+
Route("POST /KasAuth.php", servermock.ResponseFromFixture("auth_fault.xml")).
4145
Build(t)
4246

4347
_, err := client.Authentication(t.Context(), 60, false)

0 commit comments

Comments
 (0)