-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for registrant APIs (#146)
- Loading branch information
Wilson Lin
authored
Aug 24, 2023
1 parent
1d14b1b
commit e03e247
Showing
11 changed files
with
435 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package dnsimple | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
) | ||
|
||
type CreateRegistrantChangeInput struct { | ||
DomainId string `json:"domain_id"` | ||
ContactId string `json:"contact_id"` | ||
ExtendedAttributes map[string]string `json:"extended_attributes"` | ||
} | ||
|
||
type RegistrantChange struct { | ||
Id int `json:"id"` | ||
AccountId int `json:"account_id"` | ||
ContactId int `json:"contact_id"` | ||
DomainId int `json:"domain_id"` | ||
// One of: "new", "pending", "cancelling", "cancelled", "completed". | ||
State string `json:"state"` | ||
ExtendedAttributes map[string]string `json:"extended_attributes"` | ||
RegistryOwnerChange bool `json:"registry_owner_change"` | ||
IrtLockLiftedBy string `json:"irt_lock_lifted_by"` | ||
CreatedAt string `json:"created_at"` | ||
UpdatedAt string `json:"updated_at"` | ||
} | ||
|
||
type RegistrantChangeResponse struct { | ||
Response | ||
Data *RegistrantChange `json:"data"` | ||
} | ||
|
||
type RegistrantChangesListResponse struct { | ||
Response | ||
Data []RegistrantChange `json:"data"` | ||
} | ||
|
||
type RegistrantChangeListOptions struct { | ||
// Only include results with a state field exactly matching the given string | ||
State *string `url:"state,omitempty"` | ||
// Only include results with a domain_id field exactly matching the given string | ||
DomainId *string `url:"domain_id,omitempty"` | ||
// Only include results with a contact_id field exactly matching the given string | ||
ContactId *string `url:"contact_id,omitempty"` | ||
|
||
ListOptions | ||
} | ||
|
||
type CheckRegistrantChangeInput struct { | ||
DomainId string `json:"domain_id"` | ||
ContactId string `json:"contact_id"` | ||
} | ||
|
||
type ExtendedAttribute struct { | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
Required bool `json:"required"` | ||
Options []ExtendedAttributeOption `json:"options"` | ||
} | ||
|
||
type ExtendedAttributeOption struct { | ||
Title string `json:"title"` | ||
Value string `json:"value"` | ||
Description string `json:"description"` | ||
} | ||
|
||
type RegistrantChangeCheck struct { | ||
DomainId int `json:"domain_id"` | ||
ContactId int `json:"contact_id"` | ||
ExtendedAttributes []ExtendedAttribute `json:"extended_attributes"` | ||
RegistryOwnerChange bool `json:"registry_owner_change"` | ||
} | ||
|
||
type RegistrantChangeCheckResponse struct { | ||
Response | ||
Data *RegistrantChangeCheck `json:"data"` | ||
} | ||
|
||
type RegistrantChangeDeleteResponse struct { | ||
Response | ||
} | ||
|
||
// ListRegistrantChange lists registrant changes in the account. | ||
// | ||
// See https://developer.dnsimple.com/v2/registrar/#listRegistrantChanges | ||
func (s *RegistrarService) ListRegistrantChange(ctx context.Context, accountID string, options *RegistrantChangeListOptions) (*RegistrantChangesListResponse, error) { | ||
path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes", accountID)) | ||
changeResponse := &RegistrantChangesListResponse{} | ||
|
||
resp, err := s.client.get(ctx, path, changeResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
changeResponse.HTTPResponse = resp | ||
return changeResponse, nil | ||
} | ||
|
||
// CreateRegistrantChange starts a registrant change. | ||
// | ||
// See https://developer.dnsimple.com/v2/registrar/#createRegistrantChange | ||
func (s *RegistrarService) CreateRegistrantChange(ctx context.Context, accountID string, input *CreateRegistrantChangeInput) (*RegistrantChangeResponse, error) { | ||
path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes", accountID)) | ||
changeResponse := &RegistrantChangeResponse{} | ||
|
||
resp, err := s.client.post(ctx, path, input, changeResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
changeResponse.HTTPResponse = resp | ||
return changeResponse, nil | ||
} | ||
|
||
// CheckRegistrantChange retrieves the requirements of a registrant change. | ||
// | ||
// See https://developer.dnsimple.com/v2/registrar/#checkRegistrantChange | ||
func (s *RegistrarService) CheckRegistrantChange(ctx context.Context, accountID string, input *CheckRegistrantChangeInput) (*RegistrantChangeCheckResponse, error) { | ||
path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes/check", accountID)) | ||
checkResponse := &RegistrantChangeCheckResponse{} | ||
|
||
resp, err := s.client.post(ctx, path, input, checkResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
checkResponse.HTTPResponse = resp | ||
return checkResponse, nil | ||
} | ||
|
||
// GetRegistrantChange retrieves the details of an existing registrant change. | ||
// | ||
// See https://developer.dnsimple.com/v2/registrar/#getRegistrantChange | ||
func (s *RegistrarService) GetRegistrantChange(ctx context.Context, accountID string, registrantChange int) (*RegistrantChangeResponse, error) { | ||
path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes/%v", accountID, registrantChange)) | ||
checkResponse := &RegistrantChangeResponse{} | ||
|
||
resp, err := s.client.get(ctx, path, checkResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
checkResponse.HTTPResponse = resp | ||
return checkResponse, nil | ||
} | ||
|
||
// DeleteRegistrantChange cancels an ongoing registrant change from the account. | ||
// | ||
// See https://developer.dnsimple.com/v2/registrar/#deleteRegistrantChange | ||
func (s *RegistrarService) DeleteRegistrantChange(ctx context.Context, accountID string, registrantChange int) (*RegistrantChangeDeleteResponse, error) { | ||
path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes/%v", accountID, registrantChange)) | ||
deleteResponse := &RegistrantChangeDeleteResponse{} | ||
|
||
resp, err := s.client.delete(ctx, path, nil, deleteResponse) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
deleteResponse.HTTPResponse = resp | ||
return deleteResponse, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package dnsimple | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestRegistrarService_ListRegistrantChanges(t *testing.T) { | ||
setupMockServer() | ||
defer teardownMockServer() | ||
|
||
mux.HandleFunc("/v2/1010/registrar/registrant_changes", func(w http.ResponseWriter, r *http.Request) { | ||
httpResponse := httpResponseFixture(t, "/api/listRegistrantChanges/success.http") | ||
|
||
testMethod(t, r, "GET") | ||
testHeaders(t, r) | ||
|
||
w.WriteHeader(httpResponse.StatusCode) | ||
_, _ = io.Copy(w, httpResponse.Body) | ||
}) | ||
|
||
res, err := client.Registrar.ListRegistrantChange(context.Background(), "1010", &RegistrantChangeListOptions{}) | ||
|
||
assert.NoError(t, err) | ||
changes := res.Data | ||
assert.Equal(t, changes[0], RegistrantChange{ | ||
Id: 101, | ||
AccountId: 101, | ||
DomainId: 101, | ||
ContactId: 101, | ||
State: "new", | ||
ExtendedAttributes: map[string]string{}, | ||
RegistryOwnerChange: true, | ||
IrtLockLiftedBy: "", | ||
CreatedAt: "2017-02-03T17:43:22Z", | ||
UpdatedAt: "2017-02-03T17:43:22Z", | ||
}) | ||
} | ||
|
||
func TestRegistrarService_CreateRegistrantChange(t *testing.T) { | ||
setupMockServer() | ||
defer teardownMockServer() | ||
|
||
mux.HandleFunc("/v2/1010/registrar/registrant_changes", func(w http.ResponseWriter, r *http.Request) { | ||
httpResponse := httpResponseFixture(t, "/api/createRegistrantChange/success.http") | ||
|
||
testMethod(t, r, "POST") | ||
testHeaders(t, r) | ||
|
||
w.WriteHeader(httpResponse.StatusCode) | ||
_, _ = io.Copy(w, httpResponse.Body) | ||
}) | ||
|
||
res, err := client.Registrar.CreateRegistrantChange(context.Background(), "1010", &CreateRegistrantChangeInput{ | ||
DomainId: "example.com", | ||
ContactId: "101", | ||
ExtendedAttributes: map[string]string{}, | ||
}) | ||
|
||
assert.NoError(t, err) | ||
change := res.Data | ||
assert.Equal(t, change, &RegistrantChange{ | ||
Id: 101, | ||
AccountId: 101, | ||
DomainId: 101, | ||
ContactId: 101, | ||
State: "new", | ||
ExtendedAttributes: map[string]string{}, | ||
RegistryOwnerChange: true, | ||
IrtLockLiftedBy: "", | ||
CreatedAt: "2017-02-03T17:43:22Z", | ||
UpdatedAt: "2017-02-03T17:43:22Z", | ||
}) | ||
} | ||
|
||
func TestRegistrarService_CheckRegistrantChange(t *testing.T) { | ||
setupMockServer() | ||
defer teardownMockServer() | ||
|
||
mux.HandleFunc("/v2/1010/registrar/registrant_changes/check", func(w http.ResponseWriter, r *http.Request) { | ||
httpResponse := httpResponseFixture(t, "/api/checkRegistrantChange/success.http") | ||
|
||
testMethod(t, r, "POST") | ||
testHeaders(t, r) | ||
|
||
w.WriteHeader(httpResponse.StatusCode) | ||
_, _ = io.Copy(w, httpResponse.Body) | ||
}) | ||
|
||
res, err := client.Registrar.CheckRegistrantChange(context.Background(), "1010", &CheckRegistrantChangeInput{ | ||
DomainId: "example.com", | ||
ContactId: "101", | ||
}) | ||
|
||
assert.NoError(t, err) | ||
change := res.Data | ||
assert.Equal(t, change, &RegistrantChangeCheck{ | ||
DomainId: 101, | ||
ContactId: 101, | ||
ExtendedAttributes: make([]ExtendedAttribute, 0), | ||
RegistryOwnerChange: true, | ||
}) | ||
} | ||
|
||
func TestRegistrarService_GetRegistrantChange(t *testing.T) { | ||
setupMockServer() | ||
defer teardownMockServer() | ||
|
||
mux.HandleFunc("/v2/1010/registrar/registrant_changes/101", func(w http.ResponseWriter, r *http.Request) { | ||
httpResponse := httpResponseFixture(t, "/api/getRegistrantChange/success.http") | ||
|
||
testMethod(t, r, "GET") | ||
testHeaders(t, r) | ||
|
||
w.WriteHeader(httpResponse.StatusCode) | ||
_, _ = io.Copy(w, httpResponse.Body) | ||
}) | ||
|
||
res, err := client.Registrar.GetRegistrantChange(context.Background(), "1010", 101) | ||
|
||
assert.NoError(t, err) | ||
change := res.Data | ||
assert.Equal(t, change, &RegistrantChange{ | ||
Id: 101, | ||
AccountId: 101, | ||
DomainId: 101, | ||
ContactId: 101, | ||
State: "new", | ||
ExtendedAttributes: map[string]string{}, | ||
RegistryOwnerChange: true, | ||
IrtLockLiftedBy: "", | ||
CreatedAt: "2017-02-03T17:43:22Z", | ||
UpdatedAt: "2017-02-03T17:43:22Z", | ||
}) | ||
} | ||
|
||
func TestRegistrarService_DeleteRegistrantChange(t *testing.T) { | ||
setupMockServer() | ||
defer teardownMockServer() | ||
|
||
mux.HandleFunc("/v2/1010/registrar/registrant_changes/101", func(w http.ResponseWriter, r *http.Request) { | ||
httpResponse := httpResponseFixture(t, "/api/deleteRegistrantChange/success.http") | ||
|
||
testMethod(t, r, "DELETE") | ||
testHeaders(t, r) | ||
|
||
w.WriteHeader(httpResponse.StatusCode) | ||
_, _ = io.Copy(w, httpResponse.Body) | ||
}) | ||
|
||
_, err := client.Registrar.DeleteRegistrantChange(context.Background(), "1010", 101) | ||
|
||
assert.NoError(t, err) | ||
} |
14 changes: 14 additions & 0 deletions
14
fixtures.http/api/checkRegistrantChange/error-contactnotfound.http
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
HTTP/1.1 404 | ||
server: nginx | ||
date: Tue, 22 Aug 2023 13:59:02 GMT | ||
content-type: application/json; charset=utf-8 | ||
x-ratelimit-limit: 2400 | ||
x-ratelimit-remaining: 2398 | ||
x-ratelimit-reset: 1692716201 | ||
x-work-with-us: Love automation? So do we! https://dnsimple.com/jobs | ||
cache-control: no-cache | ||
x-request-id: b1dd3f42-ebb9-42fd-a121-d595de96f667 | ||
x-runtime: 0.019122 | ||
strict-transport-security: max-age=63072000 | ||
|
||
{"message":"Contact `21` not found"} |
15 changes: 15 additions & 0 deletions
15
fixtures.http/api/checkRegistrantChange/error-domainnotfound.http
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
HTTP/1.1 404 | ||
server: nginx | ||
date: Tue, 22 Aug 2023 11:09:40 GMT | ||
content-type: application/json; charset=utf-8 | ||
x-ratelimit-limit: 2400 | ||
x-ratelimit-remaining: 2395 | ||
x-ratelimit-reset: 1692705338 | ||
x-work-with-us: Love automation? So do we! https://dnsimple.com/jobs | ||
etag: W/"cef1e7d85d0b9bfd25e81b812891d34f" | ||
cache-control: max-age=0, private, must-revalidate | ||
x-request-id: 5b0d8bfb-7b6a-40b5-a079-b640fd817e34 | ||
x-runtime: 3.066249 | ||
strict-transport-security: max-age=63072000 | ||
|
||
{"message":"Domain `dnsimple-rraform.bio` not found"} |
Oops, something went wrong.