Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement registrar methods for Domain Prices API #103

Merged
merged 10 commits into from
Apr 20, 2021
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ go:
matrix:
allow_failures:
- go: tip
- go: "1.15"

script:
- ./test.sh
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#### master

- NEW: Added Registrar.GetDomainPrices() to retrieve whether a domain is premium and the prices to register, transfer, and renew. (dnsimple/dnsimple-go#103)

Incompatible changes:

- CHANGED: Domain.ExpiresOn has been replaced by Domain.ExpiresAt. (dnsimple/dnsimple-go#98)
Expand Down
36 changes: 32 additions & 4 deletions dnsimple/registrar.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,35 @@ func (s *RegistrarService) GetDomainPremiumPrice(ctx context.Context, accountID
return priceResponse, nil
}

// DomainRegistration represents the result of a domain renewal call.
// DomainPrice represents the result of a domain prices call.
type DomainPrice struct {
Domain string `json:"domain"`
Premium bool `json:"premium"`
RegistrationPrice float64 `json:"registration_price"`
RenewalPrice float64 `json:"renewal_price"`
TransferPrice float64 `json:"transfer_price"`
}

// DomainPriceResponse represents a response from an API method that results in a domain price list.
duduribeiro marked this conversation as resolved.
Show resolved Hide resolved
type DomainPriceResponse struct {
Response
Data *DomainPrice `json:"data"`
}

func (s *RegistrarService) GetDomainPrices(ctx context.Context, accountID string, domainName string) (*DomainPriceResponse, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are missing the docs here. It breaks the lint.

➜  dnsimple-go git:(implement_domain_prices) ✗ golint ./...
dnsimple/registrar.go:110:1: exported method RegistrarService.GetDomainPrices should have comment or be unexported

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weppos thanks!

shouldn't we add this on CI? thanks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would be great. Sadly, it's a bit complicated:

  1. I tried to add a Makefile in the past b7733b8, sadly once you add a Makefile Travis will rely entirely on it and you will need a non trivial amount of customization to make the build pass in both module and non-module versions. Things would be easier if we would only use module-aware versions (1.11 or above).
  2. golint is not enough to break the build. It's a highly recommended standard. We could add it as golint ./... in the travis.yml file, but it would cause the build to break if anything is invalid (and right now we have one lint warning). The current warning is actually a false positive due to a naming conflict between the webook package and the Webhook as result of the Webhook API. I am not sure how to ignore this as golint doesn't have a way to address false positives. We should probably upgrade to golangci-lint which instead does.

path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/prices", accountID, domainName))
pricesResponse := &DomainPriceResponse{}

resp, err := s.client.get(ctx, path, pricesResponse)
if err != nil {
return nil, err
}

pricesResponse.HTTPResponse = resp
return pricesResponse, nil
}

// DomainRegistration represents the result of a domain registration call.
type DomainRegistration struct {
ID int64 `json:"id"`
DomainID int64 `json:"domain_id"`
Expand Down Expand Up @@ -130,7 +158,7 @@ type RegisterDomainInput struct {

// RegisterDomain registers a domain name.
//
// See https://developer.dnsimple.com/v2/registrar/#register
// See https://developer.dnsimple.com/v2/registrar/#registerDomain
func (s *RegistrarService) RegisterDomain(ctx context.Context, accountID string, domainName string, input *RegisterDomainInput) (*DomainRegistrationResponse, error) {
path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/registrations", accountID, domainName))
registrationResponse := &DomainRegistrationResponse{}
Expand All @@ -146,7 +174,7 @@ func (s *RegistrarService) RegisterDomain(ctx context.Context, accountID string,
return registrationResponse, nil
}

// DomainTransfer represents the result of a domain renewal call.
// DomainTransfer represents the result of a domain transfer call.
type DomainTransfer struct {
ID int64 `json:"id"`
DomainID int64 `json:"domain_id"`
Expand Down Expand Up @@ -284,7 +312,7 @@ type RenewDomainInput struct {

// RenewDomain renews a domain name.
//
// See https://developer.dnsimple.com/v2/registrar/#register
// See https://developer.dnsimple.com/v2/registrar/#renewDomain
func (s *RegistrarService) RenewDomain(ctx context.Context, accountID string, domainName string, input *RenewDomainInput) (*DomainRenewalResponse, error) {
path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/renewals", accountID, domainName))
renewalResponse := &DomainRenewalResponse{}
Expand Down
41 changes: 41 additions & 0 deletions dnsimple/registrar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,47 @@ func TestRegistrarService_GetDomainPremiumPrice_WithOptions(t *testing.T) {
}
}

func TestRegistrarService_GetDomainPrices(t *testing.T) {
setupMockServer()
defer teardownMockServer()

mux.HandleFunc("/v2/1010/registrar/domains/bingo.pizza/prices", func(w http.ResponseWriter, r *http.Request) {
httpResponse := httpResponseFixture(t, "/api/getDomainPrices/success.http")

testMethod(t, r, "GET")
testHeaders(t, r)

w.WriteHeader(httpResponse.StatusCode)
_, _ = io.Copy(w, httpResponse.Body)
})

checkResponse, err := client.Registrar.GetDomainPrices(context.Background(), "1010", "bingo.pizza")
if err != nil {
t.Fatalf("Registrar.GetDomainPrices() returned error: %v", err)
}

check := checkResponse.Data
if want, got := "bingo.pizza", check.Domain; want != got {
t.Fatalf("Registrar.GetDomainPrices() returned Domain expected to be `%v`, got `%v`", want, got)
}

if want, got := true, check.Premium; want != got {
t.Fatalf("Registrar.GetDomainPrices() returned Premium expected to be `%v`, got `%v`", want, got)
}

if want, got := float64(20.0), check.RegistrationPrice; want != got {
t.Fatalf("Registrar.GetDomainPrices() returned RegistrationPrice expected to be `%v`, got `%v`", want, got)
}

if want, got := float64(20.0), check.RenewalPrice; want != got {
t.Fatalf("Registrar.GetDomainPrices() returned RenewalPrice expected to be `%v`, got `%v`", want, got)
}

if want, got := float64(20.0), check.TransferPrice; want != got {
t.Fatalf("Registrar.GetDomainPrices() returned TransferPrice expected to be `%v`, got `%v`", want, got)
}
}

func TestRegistrarService_RegisterDomain(t *testing.T) {
setupMockServer()
defer teardownMockServer()
Expand Down
20 changes: 20 additions & 0 deletions fixtures.http/api/getDomainPrices/failure.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
HTTP/1.1 400 Bad Request
Server: nginx
Date: Mon, 08 Mar 2021 14:35:58 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: identity
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2396
X-RateLimit-Reset: 1615217645
Cache-Control: no-cache
X-Request-Id: e414a674-63bb-4e54-b714-db5b516bb190
X-Runtime: 0.009579
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Content-Security-Policy: frame-ancestors 'none'

{"message":"TLD .PINEAPPLE is not supported"}
22 changes: 22 additions & 0 deletions fixtures.http/api/getDomainPrices/success.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 08 Mar 2021 14:35:26 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: identity
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2397
X-RateLimit-Reset: 1615217645
ETag: W/"2104f27f2877f429295359cfc409f9f7"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: b0d9e000-58a6-4254-af43-8735d26e12d9
X-Runtime: 9.129301
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Content-Security-Policy: frame-ancestors 'none'
Strict-Transport-Security: max-age=31536000

{"data":{"domain":"bingo.pizza","premium":true,"registration_price":20.0,"renewal_price":20.0,"transfer_price":20.0}}