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 betas to support self serve beta program #356

Merged
merged 10 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
99 changes: 99 additions & 0 deletions betas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package linodego

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

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

// Beta Program is a new product or service that is not generally available to all Akamai customers.
// Users must enroll into a beta in order to access the functionality.
type BetaProgram struct {
Label string `json:"label"`
ID string `json:"id"`
Description string `json:"description"`

// Start date of the beta program.
Started *time.Time `json:"-"`

// End date of the beta program.
Ended *time.Time `json:"-"`

// Greenlight is a program that allows customers to gain access to
// certain beta programs and to collect direct feedback from those customers.
GreenlightOnly bool `json:"greenlight_only"`

// Link to product marketing page for the beta program.
MoreInfo string `json:"more_info"`
}

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

// endpoint gets the endpoint URL for BetaProgram
func (BetasPagedResponse) endpoint(_ ...any) string {
return "/betas"
}

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

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

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

beta.Started = (*time.Time)(p.Started)
beta.Ended = (*time.Time)(p.Ended)

return nil
}

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

// ListBetaPrograms lists active beta programs
func (c *Client) ListBetaPrograms(ctx context.Context, opts *ListOptions) ([]BetaProgram, error) {
response := BetasPagedResponse{}
err := c.listHelper(ctx, &response, opts)
if err != nil {
return nil, err
}
return response.Data, nil
}

// GetBetaProgram gets the beta program's detail with the ID
func (c *Client) GetBetaProgram(ctx context.Context, betaID string) (*BetaProgram, error) {
req := c.R(ctx).SetResult(&BetaProgram{})
betaID = url.PathEscape(betaID)
b := fmt.Sprintf("betas/%s", betaID)
r, err := coupleAPIErrors(req.Get(b))
if err != nil {
return nil, err
}

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

import (
"context"
"testing"

"github.com/linode/linodego"
)

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

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

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

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

betaID := "active_closed"
beta, err := client.GetBetaProgram(context.Background(), betaID)

if err != nil {
t.Errorf("Error getting 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)
}

}
62 changes: 62 additions & 0 deletions test/integration/fixtures/TestBetaProgram_Get.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
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/betas/active_closed
method: GET
response:
body: '{"id": "active_closed", "label": "active closed beta", "description": "An
active closed beta", "started": "2018-01-02T03:04:05", "ended": null, "greenlight_only":
true, "more_info": "a link with even more info"}'
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-Length:
- "211"
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Authorization, X-Filter
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- '*'
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: ""
64 changes: 64 additions & 0 deletions test/integration/fixtures/TestBetaPrograms_List.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
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/betas
method: GET
response:
body: '{"data": [{"id": "active_closed", "label": "active closed beta",
"description": "An active closed beta", "started": "2023-07-19T15:23:43",
"ended": null, "greenlight_only": true, "more_info": "a link with even more info"},
{"id": "limited", "label": "limited beta", "description": "An active limited beta",
"started": "2023-07-19T15:23:43", "ended": null, "greenlight_only": false,
"more_info": "a link with even more info"}], "page": 1, "pages": 1, "results": 2}'
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:
- '*'
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: ""