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 all commits
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 an account is enrolled in.
type AccountBetaProgram struct {
Label string `json:"label"`
ID string `json:"id"`
Description string `json:"description"`
Started *time.Time `json:"-"`
Ended *time.Time `json:"-"`

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

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

// AccountBetasPagedResponse represents a paginated Account Beta Programs API response
type AccountBetasPagedResponse struct {
*PageOptions
Data []AccountBetaProgram `json:"data"`
}

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

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

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 *AccountBetasPagedResponse) castResult(r *resty.Request, e string) (int, int, error) {
res, err := coupleAPIErrors(r.SetResult(AccountBetasPagedResponse{}).Get(e))
if err != nil {
return 0, 0, err
}
castedRes := res.Result().(*AccountBetasPagedResponse)
resp.Data = append(resp.Data, castedRes.Data...)
return castedRes.Pages, castedRes.Results, nil
}

// ListAccountBetaPrograms lists all beta programs an account is enrolled in.
func (c *Client) ListAccountBetaPrograms(ctx context.Context, opts *ListOptions) ([]AccountBetaProgram, error) {
response := AccountBetasPagedResponse{}
err := c.listHelper(ctx, &response, opts)
if err != nil {
return nil, err
}
return response.Data, nil
}

// GetAccountBetaProgram gets the details of a beta program an account is enrolled in.
func (c *Client) GetAccountBetaProgram(ctx context.Context, betaID string) (*AccountBetaProgram, error) {
req := c.R(ctx).SetResult(&AccountBetaProgram{})
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().(*AccountBetaProgram), nil
}

// JoinBetaProgram enrolls an account into a beta program.
func (c *Client) JoinBetaProgram(ctx context.Context, opts AccountBetaProgramCreateOpts) (*AccountBetaProgram, error) {
body, err := json.Marshal(opts)
if err != nil {
return nil, err
}

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

return r.Result().(*AccountBetaProgram), 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 TestAccountBetaPrograms_List(t *testing.T) {
client, teardown := createTestClient(t, "fixtures/TestAccountBetaPrograms_List")
defer teardown()

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

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

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

betaID := "cool-beta"

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

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

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

if err != nil {
t.Errorf("Error getting an Account 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/TestAccountBetaProgram_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/TestAccountBetaPrograms_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: ""