Skip to content

new: Add betas to support self serve beta program #356

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

Merged
merged 10 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ linters:
- nosnakecase
####################

# workaround to avoid linter failures of getting malformed json
- musttag

- bodyclose
- contextcheck
- nilerr
Expand Down
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.
StartDT *time.Time `json:"-"`

// End date of the beta program.
EndDT *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
StartDT *parseabletime.ParseableTime `json:"start_dt"`
EndDT *parseabletime.ParseableTime `json:"end_dt"`
}{
Mask: (*Mask)(beta),
}

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

beta.StartDT = (*time.Time)(p.StartDT)
beta.EndDT = (*time.Time)(p.EndDT)

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
}
24 changes: 24 additions & 0 deletions test/integration/betas_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
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)
}

// TODO: assert data after actual data can be retrieved from API.
// No data is expected to be returned temporarily.
if len(betas) != 0 {
t.Errorf("Expected to see none beta program returned.")
}
}
60 changes: 60 additions & 0 deletions test/integration/fixtures/TestBetaPrograms_List.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
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": [], "page": 1, "pages": 1, "results": 0}'
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:
- "49"
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:
- "800"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""