Skip to content

Commit 6b918f4

Browse files
brookatlasvetal2409
authored andcommitted
add support for "domains.ns.getInfo" api method
Signed-off-by: brookatlas <[email protected]>
1 parent 9ee560d commit 6b918f4

File tree

4 files changed

+278
-3
lines changed

4 files changed

+278
-3
lines changed

namecheap/domains_ns.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package namecheap
2+
3+
// DomainsNSService includes the following methods:
4+
// DomainsNSService.getInfo - gets info about a registered nameserver
5+
6+
// Namecheap doc: https://www.namecheap.com/support/api/methods/domains-ns/
7+
type DomainsNSService service

namecheap/domains_ns_get_info.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package namecheap
2+
3+
import (
4+
"encoding/xml"
5+
"fmt"
6+
)
7+
8+
type NameserversGetInfoResponse struct {
9+
XMLName *xml.Name `xml:"ApiResponse"`
10+
Errors *[]struct {
11+
Message *string `xml:",chardata"`
12+
Number *string `xml:"Number,attr"`
13+
} `xml:"Errors>Error"`
14+
CommandResponse *NameserversGetInfoCommandResponse `xml:"CommandResponse"`
15+
}
16+
17+
type NameserversGetInfoCommandResponse struct {
18+
DomainNameserverInfoResult *DomainNSInfoResult `xml:"DomainNSInfoResult"`
19+
}
20+
21+
type DomainNSInfoResult struct {
22+
Domain *string `xml:"Domain,attr"`
23+
Nameserver *string `xml:"Nameserver,attr"`
24+
IP *string `xml:"IP,attr"`
25+
NameserverStatuses struct {
26+
Nameservers *[]string `xml:"Status"`
27+
} `xml:"NameserverStatuses"`
28+
}
29+
30+
func (s *DomainsNSService) GetInfo(SLD string, TLD string, Nameserver string) (*NameserversGetInfoCommandResponse, error) {
31+
var response NameserversGetInfoResponse
32+
33+
params := map[string]string{
34+
"Command": "namecheap.domains.ns.getInfo",
35+
"SLD": SLD,
36+
"TLD": TLD,
37+
"Nameserver": Nameserver,
38+
}
39+
40+
_, err := s.client.DoXML(params, &response)
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
if response.Errors != nil && len(*response.Errors) > 0 {
46+
apiErr := (*response.Errors)[0]
47+
return nil, fmt.Errorf("%s (%s)", *apiErr.Message, *apiErr.Number)
48+
}
49+
50+
return response.CommandResponse, nil
51+
}

namecheap/domains_ns_get_info_test.go

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
package namecheap
2+
3+
import (
4+
"io/ioutil"
5+
"net/http"
6+
"net/http/httptest"
7+
"net/url"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestDomainNameserversGetInfo(t *testing.T) {
14+
fakeResponse := `
15+
<?xml version="1.0" encoding="UTF-8"?>
16+
<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="OK">
17+
<Errors />
18+
<RequestedCommand>namecheap.domains.ns.getInfo</RequestedCommand>
19+
<CommandResponse Type="namecheap.domains.ns.getInfo">
20+
<DomainNSInfoResult Domain="domain.com" Nameserver="ns1.domain.com" IP="12.23.23.23">
21+
<NameserverStatuses>
22+
<Status>OK</Status>
23+
<Status>Linked</Status>
24+
</NameserverStatuses>
25+
</DomainNSInfoResult>
26+
</CommandResponse>
27+
<Server>SERVER-NAME</Server>
28+
<GMTTimeDifference>+5</GMTTimeDifference>
29+
<ExecutionTime>32.76</ExecutionTime>
30+
</ApiResponse>
31+
`
32+
33+
t.Run("request_command", func(t *testing.T) {
34+
var sentBody url.Values
35+
36+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
37+
body, _ := ioutil.ReadAll(request.Body)
38+
query, _ := url.ParseQuery(string(body))
39+
sentBody = query
40+
_, _ = writer.Write([]byte(fakeResponse))
41+
}))
42+
defer mockServer.Close()
43+
44+
client := setupClient(nil)
45+
client.BaseURL = mockServer.URL
46+
47+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
48+
if err != nil {
49+
t.Fatal("Unable to get domain nameserver", err)
50+
}
51+
52+
assert.Equal(t, "namecheap.domains.ns.getInfo", sentBody.Get("Command"))
53+
})
54+
55+
t.Run("server_empty_response", func(t *testing.T) {
56+
fakeLocalResponse := ""
57+
58+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
59+
_, _ = writer.Write([]byte(fakeLocalResponse))
60+
}))
61+
defer mockServer.Close()
62+
63+
client := setupClient(nil)
64+
client.BaseURL = mockServer.URL
65+
66+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
67+
68+
assert.EqualError(t, err, "unable to parse server response: EOF")
69+
})
70+
71+
t.Run("server_non_xml_response", func(t *testing.T) {
72+
fakeLocalResponse := "non-xml response"
73+
74+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
75+
_, _ = writer.Write([]byte(fakeLocalResponse))
76+
}))
77+
defer mockServer.Close()
78+
79+
client := setupClient(nil)
80+
client.BaseURL = mockServer.URL
81+
82+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
83+
84+
assert.EqualError(t, err, "unable to parse server response: EOF")
85+
})
86+
87+
t.Run("server_broken_xml_response", func(t *testing.T) {
88+
fakeLocalResponse := "<broken></xml><response>"
89+
90+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
91+
_, _ = writer.Write([]byte(fakeLocalResponse))
92+
}))
93+
defer mockServer.Close()
94+
95+
client := setupClient(nil)
96+
client.BaseURL = mockServer.URL
97+
98+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
99+
100+
assert.EqualError(t, err, "unable to parse server response: expected element type <ApiResponse> but have <broken>")
101+
})
102+
103+
t.Run("server_respond_with_domain_not_found_error", func(t *testing.T) {
104+
fakeLocalResponse := `
105+
<?xml version="1.0" encoding="utf-8"?>
106+
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
107+
<Errors>
108+
<Error Number="2019166">Domain not found</Error>
109+
</Errors>
110+
<Warnings />
111+
<RequestedCommand>namecheap.domains.ns.getInfo</RequestedCommand>
112+
<Server>PHX01SBAPIEXT05</Server>
113+
<GMTTimeDifference>--4:00</GMTTimeDifference>
114+
<ExecutionTime>0.011</ExecutionTime>
115+
</ApiResponse>
116+
`
117+
118+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
119+
_, _ = writer.Write([]byte(fakeLocalResponse))
120+
}))
121+
defer mockServer.Close()
122+
123+
client := setupClient(nil)
124+
client.BaseURL = mockServer.URL
125+
126+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
127+
128+
assert.EqualError(t, err, "Domain not found (2019166)")
129+
})
130+
131+
t.Run("server_respond_with_domain_not_associated_with_account_error", func(t *testing.T) {
132+
fakeLocalResponse := `
133+
<?xml version="1.0" encoding="utf-8"?>
134+
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
135+
<Errors>
136+
<Error Number="2016166">Domain is not associated with your account</Error>
137+
</Errors>
138+
<Warnings />
139+
<RequestedCommand>namecheap.domains.ns.getInfo</RequestedCommand>
140+
<Server>PHX01SBAPIEXT05</Server>
141+
<GMTTimeDifference>--4:00</GMTTimeDifference>
142+
<ExecutionTime>0.011</ExecutionTime>
143+
</ApiResponse>
144+
`
145+
146+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
147+
_, _ = writer.Write([]byte(fakeLocalResponse))
148+
}))
149+
defer mockServer.Close()
150+
151+
client := setupClient(nil)
152+
client.BaseURL = mockServer.URL
153+
154+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
155+
156+
assert.EqualError(t, err, "Domain is not associated with your account (2016166)")
157+
})
158+
159+
t.Run("server_respond_with_error_from_enom", func(t *testing.T) {
160+
fakeLocalResponse := `
161+
<?xml version="1.0" encoding="utf-8"?>
162+
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
163+
<Errors>
164+
<Error Number="3031510">Error From Enom when Errorcount &lt;&gt; 0</Error>
165+
</Errors>
166+
<Warnings />
167+
<RequestedCommand>namecheap.domains.ns.getInfo</RequestedCommand>
168+
<Server>PHX01SBAPIEXT05</Server>
169+
<GMTTimeDifference>--4:00</GMTTimeDifference>
170+
<ExecutionTime>0.011</ExecutionTime>
171+
</ApiResponse>
172+
`
173+
174+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
175+
_, _ = writer.Write([]byte(fakeLocalResponse))
176+
}))
177+
defer mockServer.Close()
178+
179+
client := setupClient(nil)
180+
client.BaseURL = mockServer.URL
181+
182+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
183+
184+
assert.EqualError(t, err, "Error From Enom when Errorcount <> 0 (3031510)")
185+
})
186+
187+
t.Run("server_respond_with_unknown_error_from_enom", func(t *testing.T) {
188+
fakeLocalResponse := `
189+
<?xml version="1.0" encoding="utf-8"?>
190+
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
191+
<Errors>
192+
<Error Number="3050900">Unknown error from Enom</Error>
193+
</Errors>
194+
<Warnings />
195+
<RequestedCommand>namecheap.domains.ns.getInfo</RequestedCommand>
196+
<Server>PHX01SBAPIEXT05</Server>
197+
<GMTTimeDifference>--4:00</GMTTimeDifference>
198+
<ExecutionTime>0.011</ExecutionTime>
199+
</ApiResponse>
200+
`
201+
202+
mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
203+
_, _ = writer.Write([]byte(fakeLocalResponse))
204+
}))
205+
defer mockServer.Close()
206+
207+
client := setupClient(nil)
208+
client.BaseURL = mockServer.URL
209+
210+
_, err := client.DomainsNS.GetInfo("specific-sld", "specific-tld", "ns1.domain.com")
211+
212+
assert.EqualError(t, err, "Unknown error from Enom (3050900)")
213+
})
214+
}

namecheap/namecheap.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import (
55
"encoding/xml"
66
"errors"
77
"fmt"
8-
"github.com/hashicorp/go-cleanhttp"
9-
"github.com/namecheap/go-namecheap-sdk/v2/namecheap/internal/syncretry"
10-
"github.com/weppos/publicsuffix-go/publicsuffix"
118
"io"
129
"net/http"
1310
"net/url"
1411
"regexp"
1512
"strconv"
13+
14+
"github.com/hashicorp/go-cleanhttp"
15+
"github.com/namecheap/go-namecheap-sdk/v2/namecheap/internal/syncretry"
16+
"github.com/weppos/publicsuffix-go/publicsuffix"
1617
)
1718

1819
const (
@@ -37,6 +38,7 @@ type Client struct {
3738
BaseURL string
3839

3940
Domains *DomainsService
41+
DomainsNS *DomainsNSService
4042
DomainsDNS *DomainsDNSService
4143
}
4244

@@ -61,6 +63,7 @@ func NewClient(options *ClientOptions) *Client {
6163
client.common.client = client
6264
client.Domains = (*DomainsService)(&client.common)
6365
client.DomainsDNS = (*DomainsDNSService)(&client.common)
66+
client.DomainsNS = (*DomainsNSService)(&client.common)
6467

6568
return client
6669
}

0 commit comments

Comments
 (0)