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

new: Add account_betas to support customer enrolled beta programs #360

Merged
merged 3 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions account_betas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package linodego

import (
"context"
"encoding/json"
"fmt"
"net/url"
"time"

"github.com/go-resty/resty/v2"
"github.com/linode/linodego/internal/parseabletime"
)

// The details and enrollment information of a Beta program that a customer is enrolled in.
type CustomerBetaProgram struct {
yec-akamai marked this conversation as resolved.
Show resolved Hide resolved
Label string `json:"label"`
ID string `json:"id"`
Description string `json:"description"`
Started *time.Time `json:"-"`
Ended *time.Time `json:"-"`

// Date the customer was enrolled in the beta program.
Enrolled *time.Time `json:"-"`
}

// CustomerBetaProgramCreateOpts fields are those accepted by CreateCustomerBetaProgram
type CustomerBetaProgramCreateOpts struct {
ID string `json:"id"`
}

// CustomerBetasPagedResponse represents a paginated Customer Beta Programs API response
type CustomerBetasPagedResponse struct {
*PageOptions
Data []CustomerBetaProgram `json:"data"`
}

// endpoint gets the endpoint URL for CustomerBetaProgram
func (CustomerBetasPagedResponse) endpoint(_ ...any) string {
return "/account/betas"
}

// UnmarshalJSON implements the json.Unmarshaler interface
func (cBeta *CustomerBetaProgram) UnmarshalJSON(b []byte) error {
type Mask CustomerBetaProgram

p := struct {
*Mask
Started *parseabletime.ParseableTime `json:"started"`
Ended *parseabletime.ParseableTime `json:"ended"`
Enrolled *parseabletime.ParseableTime `json:"enrolled"`
}{
Mask: (*Mask)(cBeta),
}

if err := json.Unmarshal(b, &p); err != nil {
return err
}

cBeta.Started = (*time.Time)(p.Started)
cBeta.Ended = (*time.Time)(p.Ended)
cBeta.Enrolled = (*time.Time)(p.Enrolled)

return nil
}

func (resp *CustomerBetasPagedResponse) castResult(r *resty.Request, e string) (int, int, error) {
res, err := coupleAPIErrors(r.SetResult(CustomerBetasPagedResponse{}).Get(e))
if err != nil {
return 0, 0, err
}
castedRes := res.Result().(*CustomerBetasPagedResponse)
resp.Data = append(resp.Data, castedRes.Data...)
return castedRes.Pages, castedRes.Results, nil
}

// ListCustomerBetaPrograms lists all beta programs a customer is enrolled in.
func (c *Client) ListCustomerBetaPrograms(ctx context.Context, opts *ListOptions) ([]CustomerBetaProgram, error) {
response := CustomerBetasPagedResponse{}
err := c.listHelper(ctx, &response, opts)
if err != nil {
return nil, err
}
return response.Data, nil
}

// GetCustomerBetaProgram gets the details of a beta program a customer is enrolled in.
func (c *Client) GetCustomerBetaProgram(ctx context.Context, betaID string) (*CustomerBetaProgram, error) {
req := c.R(ctx).SetResult(&CustomerBetaProgram{})
betaID = url.PathEscape(betaID)
b := fmt.Sprintf("/account/betas/%s", betaID)
r, err := coupleAPIErrors(req.Get(b))
if err != nil {
return nil, err
}

return r.Result().(*CustomerBetaProgram), nil
}

// CreateCustomerBetaProgram enrolls a customer in a beta program.
func (c *Client) CreateCustomerBetaProgram(ctx context.Context, opts CustomerBetaProgramCreateOpts) (*CustomerBetaProgram, error) {
yec-akamai marked this conversation as resolved.
Show resolved Hide resolved
body, err := json.Marshal(opts)
if err != nil {
return nil, err
}

e := "account/betas"
req := c.R(ctx).SetResult(&CustomerBetaProgram{}).SetBody(string(body))
r, err := coupleAPIErrors(req.Post(e))
if err != nil {
return nil, err
}

return r.Result().(*CustomerBetaProgram), nil
}
50 changes: 50 additions & 0 deletions test/integration/account_betas_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package integration

import (
"context"
"testing"

"github.com/linode/linodego"
)

func TestCustomerBetaPrograms_List(t *testing.T) {
client, teardown := createTestClient(t, "fixtures/TestCustomerBetaPrograms_List")
defer teardown()

betas, err := client.ListCustomerBetaPrograms(context.Background(), &linodego.ListOptions{})
if err != nil {
t.Errorf("Error getting Customer Beta programs, expected struct, got error %v", err)
}

if len(betas) == 0 {
t.Errorf("Expected to see customer beta program returned.")
} else {
assertDateSet(t, betas[0].Enrolled)
}
}

func TestCustomerBetaProgram_Get(t *testing.T) {
client, teardown := createTestClient(t, "fixtures/TestCustomerBetaProgram_Get")
defer teardown()

betaID := "cool-beta"

// Enroll the customer into a beta program.
createOpts := linodego.CustomerBetaProgramCreateOpts{ID: betaID}

_, err := client.CreateCustomerBetaProgram(context.Background(), createOpts)
if err != nil {
t.Errorf("Error creating Customer Beta program, expected struct, got error %v", err)
}

beta, err := client.GetCustomerBetaProgram(context.Background(), betaID)

if err != nil {
t.Errorf("Error getting Customer Beta program, expected struct, got error %v", err)
}

if beta.ID != betaID {
t.Errorf("expected beta ID to be %s; got %s", betaID, beta.ID)
}

}
139 changes: 139 additions & 0 deletions test/integration/fixtures/TestCustomerBetaProgram_Get.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
version: 1
interactions:
- request:
body: '{"id":"cool-beta"}'
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- linodego/dev https://github.com/linode/linodego
url: https://api.linode.com/v4beta/account/betas
method: POST
response:
body: '{}'
headers:
Access-Control-Allow-Credentials:
- "true"
Access-Control-Allow-Headers:
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
Access-Control-Allow-Methods:
- HEAD, GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
Cache-Control:
- private, max-age=60, s-maxage=60
Content-Length:
- "2"
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- account:read_write
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
- DENY
X-Oauth-Scopes:
- '*'
X-Ratelimit-Limit:
- "1200"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- linodego/dev https://github.com/linode/linodego
url: https://api.linode.com/v4beta/account/betas/cool-beta
method: GET
response:
body: '{"id": "cool-beta", "label": "\r\n\r\nRepellat consequatur sunt qui. Fugit
eligendi ipsa et assumenda ea aspernatur esse. A itaque iste distinctio qui
voluptas eum enim ipsa. Labore ducimus sit voluptas expedita ut non.\r\n\r\nAtque
iusto est cupiditate dignissimos soluta facere sunt molestias. Tenetur labore
est est et repudiandae praesentium officiis quis. Eveniet voluptate dignissimos
laboriosam esse maiores inventore reiciendis explicabo. Voluptas perspiciatis
voluptatibus distinctio.\r\n\r\nQui sed esse iusto ipsa repudiandae id. Quo
aut omnis id tenetur odio recusandae delectus iste. Dicta exercitationem voluptatem
accusamus. Voluptatum ut nesciunt architecto maiores.\r\n\r\nRecusandae natus
rerum aut quos aliquam. Et quisquam minima earum. Quam et quod nisi est praesentium
fuga voluptas. Blanditiis veniam aut totam.\r\n\r\nAssumenda accusantium similique
non reprehenderit sint deserunt harum vero. Et qui nihil ut. Reprehenderit quam
dicta qui repellendus perspiciatis voluptatum.\r\n", "enrolled": "2018-01-02T03:04:05",
"description": "\r\n\r\nRepellat consequatur sunt qui. Fugit eligendi ipsa et
assumenda ea aspernatur esse. A itaque iste distinctio qui voluptas eum enim
ipsa. Labore ducimus sit voluptas expedita ut non.\r\n\r\nAtque iusto est cupiditate
dignissimos soluta facere sunt molestias. Tenetur labore est est et repudiandae
praesentium officiis quis. Eveniet voluptate dignissimos laboriosam esse maiores
inventore reiciendis explicabo. Voluptas perspiciatis voluptatibus distinctio.\r\n\r\nQui
sed esse iusto ipsa repudiandae id. Quo aut omnis id tenetur odio recusandae
delectus iste. Dicta exercitationem voluptatem accusamus. Voluptatum ut nesciunt
architecto maiores.\r\n\r\nRecusandae natus rerum aut quos aliquam. Et quisquam
minima earum. Quam et quod nisi est praesentium fuga voluptas. Blanditiis veniam
aut totam.\r\n\r\nAssumenda accusantium similique non reprehenderit sint deserunt
harum vero. Et qui nihil ut. Reprehenderit quam dicta qui repellendus perspiciatis
voluptatum.\r\n", "started": "2018-01-02T03:04:05", "ended": "2018-01-02T03:04:05"}'
headers:
Access-Control-Allow-Credentials:
- "true"
Access-Control-Allow-Headers:
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
Access-Control-Allow-Methods:
- HEAD, GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
Cache-Control:
- private, max-age=0, s-maxage=0, no-cache, no-store
- private, max-age=60, s-maxage=60
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Accept-Encoding
- Authorization, X-Filter
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- account:read_only
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
- DENY
X-Oauth-Scopes:
- '*'
X-Ratelimit-Limit:
- "1200"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""
85 changes: 85 additions & 0 deletions test/integration/fixtures/TestCustomerBetaPrograms_List.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- linodego/dev https://github.com/linode/linodego
url: https://api.linode.com/v4beta/account/betas
method: GET
response:
body: '{"data": [{"id": "cool-beta", "label": "\r\n\r\nRepellat consequatur sunt
qui. Fugit eligendi ipsa et assumenda ea aspernatur esse. A itaque iste distinctio
qui voluptas eum enim ipsa. Labore ducimus sit voluptas expedita ut non.\r\n\r\nAtque
iusto est cupiditate dignissimos soluta facere sunt molestias. Tenetur labore
est est et repudiandae praesentium officiis quis. Eveniet voluptate dignissimos
laboriosam esse maiores inventore reiciendis explicabo. Voluptas perspiciatis
voluptatibus distinctio.\r\n\r\nQui sed esse iusto ipsa repudiandae id. Quo
aut omnis id tenetur odio recusandae delectus iste. Dicta exercitationem voluptatem
accusamus. Voluptatum ut nesciunt architecto maiores.\r\n\r\nRecusandae natus
rerum aut quos aliquam. Et quisquam minima earum. Quam et quod nisi est praesentium
fuga voluptas. Blanditiis veniam aut totam.\r\n\r\nAssumenda accusantium similique
non reprehenderit sint deserunt harum vero. Et qui nihil ut. Reprehenderit quam
dicta qui repellendus perspiciatis voluptatum.\r\n", "enrolled": "2018-01-02T03:04:05",
"description": "\r\n\r\nRepellat consequatur sunt qui. Fugit eligendi ipsa et
assumenda ea aspernatur esse. A itaque iste distinctio qui voluptas eum enim
ipsa. Labore ducimus sit voluptas expedita ut non.\r\n\r\nAtque iusto est cupiditate
dignissimos soluta facere sunt molestias. Tenetur labore est est et repudiandae
praesentium officiis quis. Eveniet voluptate dignissimos laboriosam esse maiores
inventore reiciendis explicabo. Voluptas perspiciatis voluptatibus distinctio.\r\n\r\nQui
sed esse iusto ipsa repudiandae id. Quo aut omnis id tenetur odio recusandae
delectus iste. Dicta exercitationem voluptatem accusamus. Voluptatum ut nesciunt
architecto maiores.\r\n\r\nRecusandae natus rerum aut quos aliquam. Et quisquam
minima earum. Quam et quod nisi est praesentium fuga voluptas. Blanditiis veniam
aut totam.\r\n\r\nAssumenda accusantium similique non reprehenderit sint deserunt
harum vero. Et qui nihil ut. Reprehenderit quam dicta qui repellendus perspiciatis
voluptatum.\r\n", "started": "2018-01-02T03:04:05", "ended": "2018-01-02T03:04:05"}],
"page": 1, "pages": 1, "results": 1}'
headers:
Access-Control-Allow-Credentials:
- "true"
Access-Control-Allow-Headers:
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
Access-Control-Allow-Methods:
- HEAD, GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
Cache-Control:
- private, max-age=0, s-maxage=0, no-cache, no-store
- private, max-age=60, s-maxage=60
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Accept-Encoding
- Authorization, X-Filter
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- account:read_only
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
- DENY
X-Oauth-Scopes:
- '*'
X-Ratelimit-Limit:
- "1200"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""