From 03a0479e44a85b4bd345f0bd44040b819100e35a Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Tue, 22 Aug 2023 15:08:47 +1000 Subject: [PATCH 1/7] Initial commit --- dnsimple/registrar.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/dnsimple/registrar.go b/dnsimple/registrar.go index 12e9e00..1d55946 100644 --- a/dnsimple/registrar.go +++ b/dnsimple/registrar.go @@ -364,3 +364,46 @@ func (s *RegistrarService) RenewDomain(ctx context.Context, accountID string, do renewalResponse.HTTPResponse = resp return renewalResponse, nil } + +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"` + Type int `json:"type"` + 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"` +} + +// RegistrantChangeResponse represents a response from an API method that returns a registrant change. +type RegistrantChangeResponse struct { + Response + Data *RegistrantChange `json:"data"` +} + +// 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 +} From 32162a54d6aed100b3d54afbe53cfdf76b26640a Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Tue, 22 Aug 2023 15:52:19 +1000 Subject: [PATCH 2/7] Update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc80292..67639f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## main +## 1.2.2 (Unreleased) + +FEATURES: + +- NEW: Added `CreateRegistrantChange` to start a registrant change. (dnsimple/dnsimple-go#146) + ## 1.2.1 FEATURES: From cabd13227f3edd338c5d1eb388ac9b51231aec2f Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Wed, 23 Aug 2023 20:06:17 +1000 Subject: [PATCH 3/7] Add other APIs --- CHANGELOG.md | 4 +- dnsimple/registrar.go | 43 ------ dnsimple/registrar_registrant.go | 142 ++++++++++++++++++ .../api/checkRegistrantChange/success.http | 15 ++ .../api/createRegistrantChange/success.http | 14 ++ .../api/deleteRegistrantChange/success.http | 13 ++ .../api/getRegistrantChange/success.http | 15 ++ .../api/listRegistrantChanges/success.http | 15 ++ 8 files changed, 216 insertions(+), 45 deletions(-) create mode 100644 dnsimple/registrar_registrant.go create mode 100644 fixtures.http/api/checkRegistrantChange/success.http create mode 100644 fixtures.http/api/createRegistrantChange/success.http create mode 100644 fixtures.http/api/deleteRegistrantChange/success.http create mode 100644 fixtures.http/api/getRegistrantChange/success.http create mode 100644 fixtures.http/api/listRegistrantChanges/success.http diff --git a/CHANGELOG.md b/CHANGELOG.md index 67639f9..0f9d71c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,11 @@ ## main -## 1.2.2 (Unreleased) +## 1.3.0 (Unreleased) FEATURES: -- NEW: Added `CreateRegistrantChange` to start a registrant change. (dnsimple/dnsimple-go#146) +- NEW: Added `ListRegistrantChanges`, `CreateRegistrantChange`, `CheckRegistrantChange`, `GetRegistrantChange`, and `DeleteRegistrantChange` APIs to manage registrant changes. (dnsimple/dnsimple-go#146) ## 1.2.1 diff --git a/dnsimple/registrar.go b/dnsimple/registrar.go index 1d55946..12e9e00 100644 --- a/dnsimple/registrar.go +++ b/dnsimple/registrar.go @@ -364,46 +364,3 @@ func (s *RegistrarService) RenewDomain(ctx context.Context, accountID string, do renewalResponse.HTTPResponse = resp return renewalResponse, nil } - -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"` - Type int `json:"type"` - 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"` -} - -// RegistrantChangeResponse represents a response from an API method that returns a registrant change. -type RegistrantChangeResponse struct { - Response - Data *RegistrantChange `json:"data"` -} - -// 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 -} diff --git a/dnsimple/registrar_registrant.go b/dnsimple/registrar_registrant.go new file mode 100644 index 0000000..5cbb4a0 --- /dev/null +++ b/dnsimple/registrar_registrant.go @@ -0,0 +1,142 @@ +package dnsimple + +import ( + "context" + "fmt" +) + +type CreateRegistrantChangeInput struct { + DomainId int `json:"domain_id"` + ContactId int `json:"contact_id"` + ExtendedAttributes map[string]string `json:"extended_attributes"` +} + +type RegistrantChange struct { + Id int `json:"id"` + Type int `json:"type"` + 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 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 int `json:"domain_id"` + ContactId int `json:"contact_id"` +} + +type RegistrantChangeCheck struct { + Response + Data []RegistrantChange `json:"data"` +} + +type RegistrantChangeCheckResponse struct { + Response + Data []RegistrantChangeCheck `json:"data"` +} + +type RegistrantChangeDeleteResponse struct { + Response +} + +// ListRegistrantChange lists registrant changes in tthe account. +// +// See https://developer.dnsimple.com/v2/registrar/#listRegistrantChanges +func (s *RegistrarService) ListRegistrantChange(ctx context.Context, accountID string, options *RegistrantChangeListOptions) (*RegistrantChangeResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes", accountID)) + changeResponse := &RegistrantChangeResponse{} + + 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) (*RegistrantChangeResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes/check", accountID)) + checkResponse := &RegistrantChangeResponse{} + + 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 +} diff --git a/fixtures.http/api/checkRegistrantChange/success.http b/fixtures.http/api/checkRegistrantChange/success.http new file mode 100644 index 0000000..5d87f59 --- /dev/null +++ b/fixtures.http/api/checkRegistrantChange/success.http @@ -0,0 +1,15 @@ +HTTP/2 200 +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 + +{"data":{"domain_id":101,"contact_id":101,"extended_attributes":[],"registry_owner_change":true}} \ No newline at end of file diff --git a/fixtures.http/api/createRegistrantChange/success.http b/fixtures.http/api/createRegistrantChange/success.http new file mode 100644 index 0000000..207b9f6 --- /dev/null +++ b/fixtures.http/api/createRegistrantChange/success.http @@ -0,0 +1,14 @@ +HTTP/2 202 +server: nginx +date: Tue, 22 Aug 2023 11:11:00 GMT +content-type: application/json; charset=utf-8 +x-ratelimit-limit: 2400 +x-ratelimit-remaining: 2394 +x-ratelimit-reset: 1692705339 +x-work-with-us: Love automation? So do we! https://dnsimple.com/jobs +cache-control: no-cache +x-request-id: 26bf7ff9-2075-42b0-9431-1778c825b6b0 +x-runtime: 3.408950 +strict-transport-security: max-age=63072000 + +{"data":{"id":101,"account_id":101,"domain_id":101,"contact_id":101,"state":"new","extended_attributes":{},"registry_owner_change":true,"irt_lock_lifted_by":null,"created_at":"2017-02-03T17:43:22Z","updated_at":"2017-02-03T17:43:22Z"}} \ No newline at end of file diff --git a/fixtures.http/api/deleteRegistrantChange/success.http b/fixtures.http/api/deleteRegistrantChange/success.http new file mode 100644 index 0000000..25e3b1b --- /dev/null +++ b/fixtures.http/api/deleteRegistrantChange/success.http @@ -0,0 +1,13 @@ +HTTP/2 201 +server: nginx +date: Tue, 22 Aug 2023 11:14:44 GMT +content-type: application/json; charset=utf-8 +x-ratelimit-limit: 2400 +x-ratelimit-remaining: 2391 +x-ratelimit-reset: 1692705338 +x-work-with-us: Love automation? So do we! https://dnsimple.com/jobs +cache-control: no-cache +x-request-id: b123e1f0-aa70-4abb-95cf-34f377c83ef4 +x-runtime: 0.114839 +strict-transport-security: max-age=63072000 + diff --git a/fixtures.http/api/getRegistrantChange/success.http b/fixtures.http/api/getRegistrantChange/success.http new file mode 100644 index 0000000..8605764 --- /dev/null +++ b/fixtures.http/api/getRegistrantChange/success.http @@ -0,0 +1,15 @@ +HTTP/2 200 +server: nginx +date: Tue, 22 Aug 2023 11:13:58 GMT +content-type: application/json; charset=utf-8 +x-ratelimit-limit: 2400 +x-ratelimit-remaining: 2392 +x-ratelimit-reset: 1692705338 +x-work-with-us: Love automation? So do we! https://dnsimple.com/jobs +etag: W/"76c5d4c7579b754b94a42ac7fa37a901" +cache-control: max-age=0, private, must-revalidate +x-request-id: e910cd08-3f9c-4da4-9986-50dbe9c3bc55 +x-runtime: 0.022006 +strict-transport-security: max-age=63072000 + +{"data":{"id":101,"account_id":101,"domain_id":101,"contact_id":101,"state":"new","extended_attributes":{},"registry_owner_change":true,"irt_lock_lifted_by":null,"created_at":"2017-02-03T17:43:22Z","updated_at":"2017-02-03T17:43:22Z"}} \ No newline at end of file diff --git a/fixtures.http/api/listRegistrantChanges/success.http b/fixtures.http/api/listRegistrantChanges/success.http new file mode 100644 index 0000000..6e19aef --- /dev/null +++ b/fixtures.http/api/listRegistrantChanges/success.http @@ -0,0 +1,15 @@ +HTTP/2 200 +server: nginx +date: Tue, 22 Aug 2023 11:12:49 GMT +content-type: application/json; charset=utf-8 +x-ratelimit-limit: 2400 +x-ratelimit-remaining: 2393 +x-ratelimit-reset: 1692705338 +x-work-with-us: Love automation? So do we! https://dnsimple.com/jobs +etag: W/"0049703ea058b06346df4c0e169eac29" +cache-control: max-age=0, private, must-revalidate +x-request-id: fd0334ce-414a-4872-8889-e548e0b1410c +x-runtime: 0.030759 +strict-transport-security: max-age=63072000 + +{"data":[{"id":101,"account_id":101,"domain_id":101,"contact_id":101,"state":"new","extended_attributes":{},"registry_owner_change":true,"irt_lock_lifted_by":null,"created_at":"2017-02-03T17:43:22Z","updated_at":"2017-02-03T17:43:22Z"}],"pagination":{"current_page":1,"per_page":30,"total_entries":1,"total_pages":1}} \ No newline at end of file From 9afb50b4bfb22343124fc6fdf21def7967932522 Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Wed, 23 Aug 2023 23:35:37 +1000 Subject: [PATCH 4/7] Add tests --- dnsimple/dnsimple.go | 10 +- dnsimple/registrar_registrant.go | 34 +++- dnsimple/registrar_registrant_test.go | 158 ++++++++++++++++++ .../error-contactnotfound.http | 14 ++ .../error-domainnotfound.http | 15 ++ .../api/checkRegistrantChange/success.http | 2 +- .../api/createRegistrantChange/success.http | 2 +- .../api/deleteRegistrantChange/success.http | 2 +- .../api/getRegistrantChange/success.http | 2 +- .../api/listRegistrantChanges/success.http | 2 +- 10 files changed, 228 insertions(+), 13 deletions(-) create mode 100644 dnsimple/registrar_registrant_test.go create mode 100644 fixtures.http/api/checkRegistrantChange/error-contactnotfound.http create mode 100644 fixtures.http/api/checkRegistrantChange/error-domainnotfound.http diff --git a/dnsimple/dnsimple.go b/dnsimple/dnsimple.go index 39b82fa..02bb48d 100644 --- a/dnsimple/dnsimple.go +++ b/dnsimple/dnsimple.go @@ -262,7 +262,15 @@ func (c *Client) request(ctx context.Context, req *http.Request, obj interface{} if w, ok := obj.(io.Writer); ok { _, err = io.Copy(w, resp.Body) } else { - err = json.NewDecoder(resp.Body).Decode(obj) + var raw []byte + raw, err = io.ReadAll(resp.Body) + if err == nil { + if len(raw) == 0 { + // TODO Ignore empty body as temporary workaround for server sending Content-Type: application/json with an empty body. + } else { + err = json.Unmarshal(raw, obj) + } + } } } diff --git a/dnsimple/registrar_registrant.go b/dnsimple/registrar_registrant.go index 5cbb4a0..a41f5f8 100644 --- a/dnsimple/registrar_registrant.go +++ b/dnsimple/registrar_registrant.go @@ -27,6 +27,11 @@ type RegistrantChange struct { } type RegistrantChangeResponse struct { + Response + Data *RegistrantChange `json:"data"` +} + +type RegistrantChangesListResponse struct { Response Data []RegistrantChange `json:"data"` } @@ -47,14 +52,29 @@ type CheckRegistrantChangeInput struct { ContactId int `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 { - Response - Data []RegistrantChange `json:"data"` + 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"` + Data *RegistrantChangeCheck `json:"data"` } type RegistrantChangeDeleteResponse struct { @@ -64,9 +84,9 @@ type RegistrantChangeDeleteResponse struct { // ListRegistrantChange lists registrant changes in tthe account. // // See https://developer.dnsimple.com/v2/registrar/#listRegistrantChanges -func (s *RegistrarService) ListRegistrantChange(ctx context.Context, accountID string, options *RegistrantChangeListOptions) (*RegistrantChangeResponse, error) { +func (s *RegistrarService) ListRegistrantChange(ctx context.Context, accountID string, options *RegistrantChangeListOptions) (*RegistrantChangesListResponse, error) { path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes", accountID)) - changeResponse := &RegistrantChangeResponse{} + changeResponse := &RegistrantChangesListResponse{} resp, err := s.client.get(ctx, path, changeResponse) if err != nil { @@ -96,9 +116,9 @@ func (s *RegistrarService) CreateRegistrantChange(ctx context.Context, accountID // 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) (*RegistrantChangeResponse, error) { +func (s *RegistrarService) CheckRegistrantChange(ctx context.Context, accountID string, input *CheckRegistrantChangeInput) (*RegistrantChangeCheckResponse, error) { path := versioned(fmt.Sprintf("/%v/registrar/registrant_changes/check", accountID)) - checkResponse := &RegistrantChangeResponse{} + checkResponse := &RegistrantChangeCheckResponse{} resp, err := s.client.post(ctx, path, input, checkResponse) if err != nil { diff --git a/dnsimple/registrar_registrant_test.go b/dnsimple/registrar_registrant_test.go new file mode 100644 index 0000000..90fb587 --- /dev/null +++ b/dnsimple/registrar_registrant_test.go @@ -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: 101, + 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: 101, + 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) +} diff --git a/fixtures.http/api/checkRegistrantChange/error-contactnotfound.http b/fixtures.http/api/checkRegistrantChange/error-contactnotfound.http new file mode 100644 index 0000000..4d82ae2 --- /dev/null +++ b/fixtures.http/api/checkRegistrantChange/error-contactnotfound.http @@ -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"} \ No newline at end of file diff --git a/fixtures.http/api/checkRegistrantChange/error-domainnotfound.http b/fixtures.http/api/checkRegistrantChange/error-domainnotfound.http new file mode 100644 index 0000000..6dcc238 --- /dev/null +++ b/fixtures.http/api/checkRegistrantChange/error-domainnotfound.http @@ -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"} \ No newline at end of file diff --git a/fixtures.http/api/checkRegistrantChange/success.http b/fixtures.http/api/checkRegistrantChange/success.http index 5d87f59..0520f6c 100644 --- a/fixtures.http/api/checkRegistrantChange/success.http +++ b/fixtures.http/api/checkRegistrantChange/success.http @@ -1,4 +1,4 @@ -HTTP/2 200 +HTTP/1.1 200 server: nginx date: Tue, 22 Aug 2023 11:09:40 GMT content-type: application/json; charset=utf-8 diff --git a/fixtures.http/api/createRegistrantChange/success.http b/fixtures.http/api/createRegistrantChange/success.http index 207b9f6..79048ee 100644 --- a/fixtures.http/api/createRegistrantChange/success.http +++ b/fixtures.http/api/createRegistrantChange/success.http @@ -1,4 +1,4 @@ -HTTP/2 202 +HTTP/1.1 202 server: nginx date: Tue, 22 Aug 2023 11:11:00 GMT content-type: application/json; charset=utf-8 diff --git a/fixtures.http/api/deleteRegistrantChange/success.http b/fixtures.http/api/deleteRegistrantChange/success.http index 25e3b1b..569ad51 100644 --- a/fixtures.http/api/deleteRegistrantChange/success.http +++ b/fixtures.http/api/deleteRegistrantChange/success.http @@ -1,4 +1,4 @@ -HTTP/2 201 +HTTP/1.1 201 server: nginx date: Tue, 22 Aug 2023 11:14:44 GMT content-type: application/json; charset=utf-8 diff --git a/fixtures.http/api/getRegistrantChange/success.http b/fixtures.http/api/getRegistrantChange/success.http index 8605764..9bf625c 100644 --- a/fixtures.http/api/getRegistrantChange/success.http +++ b/fixtures.http/api/getRegistrantChange/success.http @@ -1,4 +1,4 @@ -HTTP/2 200 +HTTP/1.1 200 server: nginx date: Tue, 22 Aug 2023 11:13:58 GMT content-type: application/json; charset=utf-8 diff --git a/fixtures.http/api/listRegistrantChanges/success.http b/fixtures.http/api/listRegistrantChanges/success.http index 6e19aef..91f1519 100644 --- a/fixtures.http/api/listRegistrantChanges/success.http +++ b/fixtures.http/api/listRegistrantChanges/success.http @@ -1,4 +1,4 @@ -HTTP/2 200 +HTTP/1.1 200 server: nginx date: Tue, 22 Aug 2023 11:12:49 GMT content-type: application/json; charset=utf-8 From f29815751366a1918d00667336ed0977381576fb Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Wed, 23 Aug 2023 23:36:49 +1000 Subject: [PATCH 5/7] Fix typo --- dnsimple/registrar_registrant.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsimple/registrar_registrant.go b/dnsimple/registrar_registrant.go index a41f5f8..0a92d32 100644 --- a/dnsimple/registrar_registrant.go +++ b/dnsimple/registrar_registrant.go @@ -81,7 +81,7 @@ type RegistrantChangeDeleteResponse struct { Response } -// ListRegistrantChange lists registrant changes in tthe account. +// 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) { From 43e6f15ef5d79a2d9a588da61cd24894be53b153 Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Thu, 24 Aug 2023 00:19:04 +1000 Subject: [PATCH 6/7] Fix types --- dnsimple/registrar_registrant.go | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsimple/registrar_registrant.go b/dnsimple/registrar_registrant.go index 0a92d32..c361902 100644 --- a/dnsimple/registrar_registrant.go +++ b/dnsimple/registrar_registrant.go @@ -13,7 +13,6 @@ type CreateRegistrantChangeInput struct { type RegistrantChange struct { Id int `json:"id"` - Type int `json:"type"` AccountId int `json:"account_id"` ContactId int `json:"contact_id"` DomainId int `json:"domain_id"` From a0bab607f157c5a7a5600ef8036c3a8a7bbd4d4f Mon Sep 17 00:00:00 2001 From: DXTimer Date: Thu, 24 Aug 2023 12:11:07 +0700 Subject: [PATCH 7/7] change: input types and rename files --- ...trar_registrant.go => registrar_registrant_changes.go} | 8 ++++---- ...trant_test.go => registrar_registrant_changes_test.go} | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) rename dnsimple/{registrar_registrant.go => registrar_registrant_changes.go} (96%) rename dnsimple/{registrar_registrant_test.go => registrar_registrant_changes_test.go} (97%) diff --git a/dnsimple/registrar_registrant.go b/dnsimple/registrar_registrant_changes.go similarity index 96% rename from dnsimple/registrar_registrant.go rename to dnsimple/registrar_registrant_changes.go index c361902..b8858fb 100644 --- a/dnsimple/registrar_registrant.go +++ b/dnsimple/registrar_registrant_changes.go @@ -6,8 +6,8 @@ import ( ) type CreateRegistrantChangeInput struct { - DomainId int `json:"domain_id"` - ContactId int `json:"contact_id"` + DomainId string `json:"domain_id"` + ContactId string `json:"contact_id"` ExtendedAttributes map[string]string `json:"extended_attributes"` } @@ -47,8 +47,8 @@ type RegistrantChangeListOptions struct { } type CheckRegistrantChangeInput struct { - DomainId int `json:"domain_id"` - ContactId int `json:"contact_id"` + DomainId string `json:"domain_id"` + ContactId string `json:"contact_id"` } type ExtendedAttribute struct { diff --git a/dnsimple/registrar_registrant_test.go b/dnsimple/registrar_registrant_changes_test.go similarity index 97% rename from dnsimple/registrar_registrant_test.go rename to dnsimple/registrar_registrant_changes_test.go index 90fb587..92e548f 100644 --- a/dnsimple/registrar_registrant_test.go +++ b/dnsimple/registrar_registrant_changes_test.go @@ -56,8 +56,8 @@ func TestRegistrarService_CreateRegistrantChange(t *testing.T) { }) res, err := client.Registrar.CreateRegistrantChange(context.Background(), "1010", &CreateRegistrantChangeInput{ - DomainId: 101, - ContactId: 101, + DomainId: "example.com", + ContactId: "101", ExtendedAttributes: map[string]string{}, }) @@ -92,8 +92,8 @@ func TestRegistrarService_CheckRegistrantChange(t *testing.T) { }) res, err := client.Registrar.CheckRegistrantChange(context.Background(), "1010", &CheckRegistrantChangeInput{ - DomainId: 101, - ContactId: 101, + DomainId: "example.com", + ContactId: "101", }) assert.NoError(t, err)