Skip to content

Commit

Permalink
support nameservers update
Browse files Browse the repository at this point in the history
Signed-off-by: brookatlas <[email protected]>
  • Loading branch information
brookatlas authored and vetal2409 committed May 7, 2024
1 parent 557bfcb commit 34a6c80
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 0 deletions.
50 changes: 50 additions & 0 deletions namecheap/domains_ns_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package namecheap

import (
"encoding/xml"
"fmt"
)

type NameserversUpdateResponse struct {
XMLName *xml.Name `xml:"ApiResponse"`
Errors *[]struct {
Message *string `xml:",chardata"`
Number *string `xml:"Number,attr"`
} `xml:"Errors>Error"`
CommandResponse *NameserversCreateCommandResponse `xml:"CommandResponse"`
}

type NameserversUpdateCommandResponse struct {
DomainNameserverUpdateResult *DomainsNSUpdateResult `xml:"DomainNSUpdateResult"`
}

type DomainsNSUpdateResult struct {
Domain *string `xml:"Domain,attr"`
Nameserver *string `xml:"Nameserver,attr"`
IsSuccess *bool `xml:"IsSuccess,attr"`
}

func (s *DomainsNSService) Update(SLD string, TLD string, Nameserver string, OldIP string, IP string) (*NameserversCreateCommandResponse, error) {
var response NameserversUpdateResponse

params := map[string]string{
"Command": "namecheap.domains.ns.update",
"SLD": SLD,
"TLD": TLD,
"Nameserver": Nameserver,
"OldIP": OldIP,
"IP": IP,
}

_, err := s.client.DoXML(params, &response)
if err != nil {
return nil, err
}

if response.Errors != nil && len(*response.Errors) > 0 {
apiErr := (*response.Errors)[0]
return nil, fmt.Errorf("%s (%s)", *apiErr.Message, *apiErr.Number)
}

return response.CommandResponse, nil
}
209 changes: 209 additions & 0 deletions namecheap/domains_ns_update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package namecheap

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"testing"

"github.com/stretchr/testify/assert"
)

func TestDomainNameserversUpdate(t *testing.T) {
fakeResponse := `
<?xml version="1.0" encoding="UTF-8"?>
<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="OK">
<Errors />
<RequestedCommand>namecheap.domains.ns.update</RequestedCommand>
<CommandResponse Type="namecheap.domains.ns.update">
<DomainNSUpdateResult Domain="domain.com" Nameserver="ns1.domain.com" IsSuccess="true" />
</CommandResponse>
<Server>SEVER-ONE</Server>
<GMTTimeDifference>+5</GMTTimeDifference>
<ExecutionTime>32.76</ExecutionTime>
</ApiResponse>
`

t.Run("request_command", func(t *testing.T) {
var sentBody url.Values

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
body, _ := ioutil.ReadAll(request.Body)
query, _ := url.ParseQuery(string(body))
sentBody = query
_, _ = writer.Write([]byte(fakeResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")
if err != nil {
t.Fatal("Unable to get domain nameserver", err)
}

assert.Equal(t, "namecheap.domains.ns.update", sentBody.Get("Command"))
})

t.Run("server_empty_response", func(t *testing.T) {
fakeLocalResponse := ""

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "unable to parse server response: EOF")
})

t.Run("server_non_xml_response", func(t *testing.T) {
fakeLocalResponse := "non-xml response"

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "unable to parse server response: EOF")
})

t.Run("server_broken_xml_response", func(t *testing.T) {
fakeLocalResponse := "<broken></xml><response>"

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "unable to parse server response: expected element type <ApiResponse> but have <broken>")
})

t.Run("server_respond_with_domain_not_found_error", func(t *testing.T) {
fakeLocalResponse := `
<?xml version="1.0" encoding="utf-8"?>
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
<Errors>
<Error Number="2019166">Domain not found</Error>
</Errors>
<Warnings />
<RequestedCommand>namecheap.domains.ns.update</RequestedCommand>
<Server>PHX01SBAPIEXT05</Server>
<GMTTimeDifference>--4:00</GMTTimeDifference>
<ExecutionTime>0.011</ExecutionTime>
</ApiResponse>
`

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "Domain not found (2019166)")
})

t.Run("server_respond_with_domain_not_associated_with_account_error", func(t *testing.T) {
fakeLocalResponse := `
<?xml version="1.0" encoding="utf-8"?>
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
<Errors>
<Error Number="2016166">Domain is not associated with your account</Error>
</Errors>
<Warnings />
<RequestedCommand>namecheap.domains.ns.update</RequestedCommand>
<Server>PHX01SBAPIEXT05</Server>
<GMTTimeDifference>--4:00</GMTTimeDifference>
<ExecutionTime>0.011</ExecutionTime>
</ApiResponse>
`

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "Domain is not associated with your account (2016166)")
})

t.Run("server_respond_with_error_from_enom", func(t *testing.T) {
fakeLocalResponse := `
<?xml version="1.0" encoding="utf-8"?>
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
<Errors>
<Error Number="3031510">Error From Enom when Errorcount &lt;&gt; 0</Error>
</Errors>
<Warnings />
<RequestedCommand>namecheap.domains.ns.update</RequestedCommand>
<Server>PHX01SBAPIEXT05</Server>
<GMTTimeDifference>--4:00</GMTTimeDifference>
<ExecutionTime>0.011</ExecutionTime>
</ApiResponse>
`

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "Error From Enom when Errorcount <> 0 (3031510)")
})

t.Run("server_respond_with_unknown_error_from_enom", func(t *testing.T) {
fakeLocalResponse := `
<?xml version="1.0" encoding="utf-8"?>
<ApiResponse Status="ERROR" xmlns="http://api.namecheap.com/xml.response">
<Errors>
<Error Number="3050900">Unknown error from Enom</Error>
</Errors>
<Warnings />
<RequestedCommand>namecheap.domains.ns.update</RequestedCommand>
<Server>PHX01SBAPIEXT05</Server>
<GMTTimeDifference>--4:00</GMTTimeDifference>
<ExecutionTime>0.011</ExecutionTime>
</ApiResponse>
`

mockServer := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = writer.Write([]byte(fakeLocalResponse))
}))
defer mockServer.Close()

client := setupClient(nil)
client.BaseURL = mockServer.URL

_, err := client.DomainsNS.Update("specific-sld", "specific-tld", "ns1.domain.com", "specific-old-ip", "specific-new-ip")

assert.EqualError(t, err, "Unknown error from Enom (3050900)")
})
}

0 comments on commit 34a6c80

Please sign in to comment.