Skip to content

Commit

Permalink
adds test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
ashwiniag committed Dec 22, 2024
1 parent dc557a6 commit 6fd60f5
Show file tree
Hide file tree
Showing 6 changed files with 385 additions and 1 deletion.
1 change: 0 additions & 1 deletion internal/restapi/v1/integrations/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
)

type UpdateIntegrationRequest struct {
// ToDo: convert to UUID
ID uuid.UUID `path:"id"`
Name *string `json:"name"`
Type *string `json:"type"`
Expand Down
58 changes: 58 additions & 0 deletions internal/restapi/v1/policies/delete_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package policies_test

import (
"context"
"github.com/google/uuid"
_ "github.com/mattn/go-sqlite3"
"github.com/shinobistack/gokakashi/ent/enttest"
policyent "github.com/shinobistack/gokakashi/ent/policies"
"github.com/shinobistack/gokakashi/ent/schema"
"github.com/shinobistack/gokakashi/internal/restapi/v1/policies"
"github.com/stretchr/testify/assert"
"testing"
)

func TestDeletePolicy_ValidDeletion(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

// Create a policy
policy := client.Policies.Create().
SetName("to-be-deleted-test-policy").
SetImage(schema.Image{Registry: "example-registry", Name: "example-name", Tags: []string{"v1.0"}}).
SaveX(context.Background())
req := policies.DeletePolicyRequest{ID: policy.ID}
res := &policies.DeletePolicyResponse{}
err := policies.DeletePolicy(client)(context.Background(), req, res)

assert.NoError(t, err)
assert.Equal(t, policy.ID, res.ID)

// Verify deletion
exists := client.Policies.Query().Where(policyent.ID(policy.ID)).ExistX(context.Background())
assert.False(t, exists)
}

func TestDeletePolicy_InvalidUUID(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.DeletePolicyRequest{ID: uuid.Nil}
res := &policies.DeletePolicyResponse{}
err := policies.DeletePolicy(client)(context.Background(), req, res)

assert.Error(t, err)
}

func TestDeletePolicy_NonExistentID(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.DeletePolicyRequest{ID: uuid.New()}
res := &policies.DeletePolicyResponse{}
err := policies.DeletePolicy(client)(context.Background(), req, res)

assert.Error(t, err)
}

// ToDo: TestDeletePolicy_WithDependentRecords
86 changes: 86 additions & 0 deletions internal/restapi/v1/policies/get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package policies_test

import (
"context"
"github.com/google/uuid"
_ "github.com/mattn/go-sqlite3"
"github.com/shinobistack/gokakashi/ent/enttest"
"github.com/shinobistack/gokakashi/ent/schema"
"github.com/shinobistack/gokakashi/internal/restapi/v1/policies"
"github.com/stretchr/testify/assert"
"testing"
)

func TestListPolicies_EmptyDatabase(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.ListPoliciesRequest{}
res := &[]policies.GetPolicyResponse{}
err := policies.ListPolicies(client)(context.Background(), req, res)

assert.NoError(t, err)
assert.Equal(t, 0, len(*res))
}

func TestListPolicies(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

// Create test data
client.Policies.Create().
SetName("test-policy1").
SetImage(schema.Image{Registry: "example-registry", Name: "example-name", Tags: []string{"v1.0"}}).
Save(context.Background())

Check failure on line 34 in internal/restapi/v1/policies/get_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `(*github.com/shinobistack/gokakashi/ent.PoliciesCreate).Save` is not checked (errcheck)
client.Policies.Create().
SetName("test-policy2").
SetImage(schema.Image{Registry: "example-registry", Name: "example-name", Tags: []string{"v1.0"}}).
Save(context.Background())

Check failure on line 38 in internal/restapi/v1/policies/get_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `(*github.com/shinobistack/gokakashi/ent.PoliciesCreate).Save` is not checked (errcheck)

req := policies.ListPoliciesRequest{}
res := &[]policies.GetPolicyResponse{}
err := policies.ListPolicies(client)(context.Background(), req, res)

assert.NoError(t, err)
assert.Equal(t, 2, len(*res))
}

func TestGetPolicy_ValidID(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

// Create a policy
policy := client.Policies.Create().
SetName("test-policy").
SetImage(schema.Image{Registry: "example-registry", Name: "example-name", Tags: []string{"v1.0"}}).
SaveX(context.Background())

req := policies.GetPolicyRequests{ID: policy.ID}
res := &policies.GetPolicyResponse{}
err := policies.GetPolicy(client)(context.Background(), req, res)

assert.NoError(t, err)
assert.Equal(t, policy.Name, res.Name)
}

func TestGetPolicy_InvalidUUID(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.GetPolicyRequests{ID: uuid.Nil}
res := &policies.GetPolicyResponse{}
err := policies.GetPolicy(client)(context.Background(), req, res)

assert.Error(t, err)
}

func TestGetPolicy_NonExistentID(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.GetPolicyRequests{ID: uuid.New()}
res := &policies.GetPolicyResponse{}
err := policies.GetPolicy(client)(context.Background(), req, res)

assert.Error(t, err)
}
29 changes: 29 additions & 0 deletions internal/restapi/v1/policies/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"fmt"
"github.com/google/uuid"
"github.com/shinobistack/gokakashi/ent"
"github.com/shinobistack/gokakashi/ent/policies"
"github.com/shinobistack/gokakashi/ent/schema"
"github.com/swaggest/usecase/status"
"regexp"
"strings"
)

type CreatePolicyRequest struct {
Expand All @@ -31,6 +34,21 @@ func CreatePolicy(client *ent.Client) func(ctx context.Context, req CreatePolicy
return status.Wrap(errors.New("invalid image: missing required fields"), status.InvalidArgument)
}

if !isValidID(req.Name) {
return status.Wrap(errors.New("invalid id format; must be lowercase, alphanumeric, or dashes"), status.InvalidArgument)
}

// Check for duplicate name
exists, err := client.Policies.Query().
Where(policies.Name(req.Name)).
Exist(ctx)
if err != nil {
return status.Wrap(fmt.Errorf("failed to check for duplicate policies name: %v", err), status.Internal)
}
if exists {
return status.Wrap(errors.New("policy with the same name already exists"), status.AlreadyExists)
}

// Validate trigger
// ToDo: Valid cron for type: cron

Expand Down Expand Up @@ -59,3 +77,14 @@ func CreatePolicy(client *ent.Client) func(ctx context.Context, req CreatePolicy
return nil
}
}

// isValidID validates the ID format:
// - All lowercase letters.
// - Multiple words separated by dashes (`-`).
// - No spaces at the beginning or end.
// - No special characters other than hyphen.
func isValidID(id string) bool {
id = strings.TrimSpace(id)
regex := regexp.MustCompile(`^[a-z]+(-[a-z]+)*$`)
return regex.MatchString(id)
}
124 changes: 124 additions & 0 deletions internal/restapi/v1/policies/post_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package policies_test

import (
"context"
_ "github.com/mattn/go-sqlite3"
"github.com/shinobistack/gokakashi/ent/enttest"
"github.com/shinobistack/gokakashi/ent/schema"
"github.com/shinobistack/gokakashi/internal/restapi/v1/policies"
"github.com/stretchr/testify/assert"
"testing"
)

func TestCreatepolicy_InvalidPolicyNameFormat(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.CreatePolicyRequest{
Name: "tTest-policy",
Image: schema.Image{
Registry: "example-registry",
Name: "example-name",
Tags: []string{"v1.0"},
},
Trigger: map[string]interface{}{"type": "cron", "schedule": "0 0 * * *"},
Check: &schema.Check{
Condition: "sev.high > 0",
Notify: []string{"team-slack"},
},
}
res := &policies.CreatePolicyResponse{}
err := policies.CreatePolicy(client)(context.Background(), req, res)
assert.Error(t, err)

req = policies.CreatePolicyRequest{
Name: "#test policy",
Image: schema.Image{
Registry: "example-registry",
Name: "example-name",
Tags: []string{"v1.0"},
},
Trigger: map[string]interface{}{"type": "cron", "schedule": "0 0 * * *"},
Check: &schema.Check{
Condition: "sev.high > 0",
Notify: []string{"team-slack"},
},
}
err = policies.CreatePolicy(client)(context.Background(), req, res)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid id format")
}

func TestCreatePolicy_ValidInput(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.CreatePolicyRequest{
Name: "test-policy",
Image: schema.Image{
Registry: "example-registry",
Name: "example-name",
Tags: []string{"v1.0"},
},
Trigger: map[string]interface{}{"type": "cron", "schedule": "0 0 * * *"},
Check: &schema.Check{
Condition: "sev.high > 0",
Notify: []string{"team-slack"},
},
}
res := &policies.CreatePolicyResponse{}
err := policies.CreatePolicy(client)(context.Background(), req, res)

assert.NoError(t, err)
assert.NotNil(t, res.ID)
assert.Equal(t, "created", res.Status)
}

func TestCreatePolicy_MissingFields(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

req := policies.CreatePolicyRequest{
Name: "incomplete-policy",
Image: schema.Image{
Registry: "",
Name: "example-name",
Tags: []string{},
},
Trigger: nil,
Check: nil,
}
res := &policies.CreatePolicyResponse{}
err := policies.CreatePolicy(client)(context.Background(), req, res)

assert.Error(t, err)
}

func TestCreatePolicy_DuplicateName(t *testing.T) {
client := enttest.Open(t, "sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
defer client.Close()

// Seed database
req := policies.CreatePolicyRequest{
Name: "duplicate-policy",
Image: schema.Image{
Registry: "example-registry",
Name: "example-name",
Tags: []string{"v1.0"},
},
Trigger: map[string]interface{}{"type": "cron", "schedule": "0 0 * * *"},
Check: &schema.Check{
Condition: "sev.high > 0",
Notify: []string{"team-slack"},
},
}
res := &policies.CreatePolicyResponse{}
handler := policies.CreatePolicy(client)
err := handler(context.Background(), req, res)
assert.NoError(t, err)

// Test case: Duplicate name
err = handler(context.Background(), req, res)
assert.Error(t, err)
assert.Contains(t, err.Error(), "policy with the same name already exists")
}
Loading

0 comments on commit 6fd60f5

Please sign in to comment.