Skip to content

Commit

Permalink
SCALRCORE-32442 Show who and when created/updated the variable
Browse files Browse the repository at this point in the history
  • Loading branch information
igor-melnyk-scalr committed Sep 28, 2024
1 parent 9fabdd2 commit 1361978
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 10 deletions.
32 changes: 23 additions & 9 deletions variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/url"
"time"

"github.com/google/go-querystring/query"
)
Expand Down Expand Up @@ -53,19 +54,22 @@ type VariableList struct {

// Variable represents a Scalr variable.
type Variable struct {
ID string `jsonapi:"primary,vars"`
Key string `jsonapi:"attr,key"`
Value string `jsonapi:"attr,value"`
Category CategoryType `jsonapi:"attr,category"`
Description string `jsonapi:"attr,description"`
HCL bool `jsonapi:"attr,hcl"`
Sensitive bool `jsonapi:"attr,sensitive"`
Final bool `jsonapi:"attr,final"`
ID string `jsonapi:"primary,vars"`
Key string `jsonapi:"attr,key"`
Value string `jsonapi:"attr,value"`
Category CategoryType `jsonapi:"attr,category"`
Description string `jsonapi:"attr,description"`
HCL bool `jsonapi:"attr,hcl"`
Sensitive bool `jsonapi:"attr,sensitive"`
Final bool `jsonapi:"attr,final"`
UpdatedByEmail string `jsonapi:"attr,updated-by-email"`
UpdatedAt time.Time `jsonapi:"attr,updated-at,iso8601"`

// Relations
Workspace *Workspace `jsonapi:"relation,workspace"`
Environment *Environment `jsonapi:"relation,environment"`
Account *Account `jsonapi:"relation,account"`
UpdatedBy *User `jsonapi:"relation,updated-by"`
}

// VariableListOptions represents the options for listing variables.
Expand Down Expand Up @@ -116,6 +120,9 @@ func (s *variables) List(ctx context.Context, options VariableListOptions) (*Var

type VariableWriteQueryOptions struct {
Force *bool `url:"force,omitempty"`

// The comma-separated list of relationship paths.
Include *string `url:"include,omitempty"`
}

// VariableCreateOptions represents the options for creating a new variable.
Expand Down Expand Up @@ -205,7 +212,14 @@ func (s *variables) Read(ctx context.Context, variableID string) (*Variable, err
}

u := fmt.Sprintf("vars/%s", url.QueryEscape(variableID))
req, err := s.client.newRequest("GET", u, nil)

options := struct {
Include string `url:"include"`
}{
Include: "updated-by",
}

req, err := s.client.newRequest("GET", u, &options)
if err != nil {
return nil, err
}
Expand Down
102 changes: 101 additions & 1 deletion variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,38 @@ func TestVariablesCreate(t *testing.T) {
assert.Equal(t, *options.Value, v.Value)
assert.Equal(t, *options.Category, v.Category)
assert.Equal(t, *options.Description, v.Description)
assert.NotEmpty(t, v.UpdatedByEmail)
assert.NotEmpty(t, v.UpdatedAt)
assert.NotEmpty(t, v.UpdatedBy)
assert.NotEmpty(t, v.UpdatedBy.ID)
assert.Empty(t, v.UpdatedBy.Email)
})

t.Run("with included updated-by", func(t *testing.T) {
options := VariableCreateOptions{
Key: String(randomVariableKey(t)),
Value: String(""),
Category: Category(CategoryShell),
Description: String("random variable test"),
Workspace: wsTest,
QueryOptions: &VariableWriteQueryOptions{
Include: String("updated-by"),
},
}

v, err := client.Variables.Create(ctx, options)
require.NoError(t, err)

assert.NotEmpty(t, v.ID)
assert.Equal(t, *options.Key, v.Key)
assert.Equal(t, *options.Value, v.Value)
assert.Equal(t, *options.Category, v.Category)
assert.Equal(t, *options.Description, v.Description)
assert.NotEmpty(t, v.UpdatedByEmail)
assert.NotEmpty(t, v.UpdatedAt)
assert.NotEmpty(t, v.UpdatedBy)
assert.NotEmpty(t, v.UpdatedBy.ID)
assert.Equal(t, v.UpdatedBy.Email, v.UpdatedByEmail)
})

t.Run("when options is missing value", func(t *testing.T) {
Expand Down Expand Up @@ -164,6 +196,11 @@ func TestVariablesRead(t *testing.T) {
assert.Equal(t, vTest.Key, v.Key)
assert.Equal(t, vTest.Sensitive, v.Sensitive)
assert.Equal(t, vTest.Value, v.Value)
assert.NotEmpty(t, v.UpdatedAt)
assert.NotEmpty(t, v.UpdatedByEmail)
assert.NotEmpty(t, v.UpdatedBy)
assert.NotEmpty(t, v.UpdatedBy.Email)
assert.Equal(t, v.UpdatedByEmail, v.UpdatedBy.Email)
})

t.Run("when the variable does not exist", func(t *testing.T) {
Expand Down Expand Up @@ -205,9 +242,39 @@ func TestVariablesUpdate(t *testing.T) {
require.NoError(t, err)

assert.Equal(t, *options.Key, v.Key)
assert.Equal(t, *options.HCL, v.HCL)
assert.Equal(t, false, v.HCL)
assert.Equal(t, *options.Value, v.Value)
assert.Equal(t, *options.Description, v.Description)
assert.NotEmpty(t, v.UpdatedByEmail)
assert.NotEmpty(t, v.UpdatedAt)
assert.NotEmpty(t, v.UpdatedBy)
assert.NotEmpty(t, v.UpdatedBy.ID)
assert.Empty(t, v.UpdatedBy.Email)
})

t.Run("with valid options and included updated-by", func(t *testing.T) {
options := VariableUpdateOptions{
Key: String("newname"),
Value: String("newvalue"),
Description: String("newdescription"),
HCL: Bool(true),
QueryOptions: &VariableWriteQueryOptions{
Include: String("updated-by"),
},
}

v, err := client.Variables.Update(ctx, vTest.ID, options)
require.NoError(t, err)

assert.Equal(t, *options.Key, v.Key)
assert.Equal(t, false, v.HCL)
assert.Equal(t, *options.Value, v.Value)
assert.Equal(t, *options.Description, v.Description)
assert.NotEmpty(t, v.UpdatedByEmail)
assert.NotEmpty(t, v.UpdatedAt)
assert.NotEmpty(t, v.UpdatedBy)
assert.NotEmpty(t, v.UpdatedBy.ID)
assert.Equal(t, v.UpdatedBy.Email, v.UpdatedByEmail)
})

t.Run("when updating a subset of values", func(t *testing.T) {
Expand Down Expand Up @@ -242,6 +309,7 @@ func TestVariablesUpdate(t *testing.T) {
updated, err := client.Variables.Update(ctx, created.ID, VariableUpdateOptions{})
require.NoError(t, err)

updated.UpdatedAt = created.UpdatedAt
assert.Equal(t, created, updated)
})

Expand Down Expand Up @@ -344,6 +412,38 @@ func TestVariablesList(t *testing.T) {
assert.ElementsMatch(t, expectedIds, responseIds)
})

t.Run("with included updated-by", func(t *testing.T) {
variables, err := client.Variables.List(ctx, VariableListOptions{})
if err != nil {
log.Fatalf("Cant remove default variables before test: %v", err)
return
}
for _, variable := range variables.Items {
err = client.Variables.Delete(ctx, variable.ID)
if err != nil {
log.Fatalf("Cant remove default variables before test: %v", err)
return
}
}

_, deleteVar := createVariable(t, client, nil, nil, &Account{ID: defaultAccountID})
defer deleteVar()

responseVariables, err := client.Variables.List(
ctx, VariableListOptions{
Include: String("updated-by"),
})
require.NoError(t, err)

for _, variable := range responseVariables.Items {
assert.NotEmpty(t, variable.UpdatedByEmail)
assert.NotEmpty(t, variable.UpdatedAt)
assert.NotEmpty(t, variable.UpdatedBy)
assert.NotEmpty(t, variable.UpdatedBy.ID)
assert.Equal(t, variable.UpdatedBy.Email, variable.UpdatedByEmail)
}
})

t.Run("category", func(t *testing.T) {
workspace, deleteWorkspace := createWorkspace(t, client, nil)
defer deleteWorkspace()
Expand Down

0 comments on commit 1361978

Please sign in to comment.