package rulesengine import ( "errors" "testing" "github.com/stretchr/testify/assert" "edge-infra.dev/pkg/lib/uuid" ) func TestValidateCommandPayload(t *testing.T) { t.Parallel() tests := map[string]struct { payload ValidateCommandPayload expectedErr error }{ "Success": { ValidateCommandPayload{ Command: Command{ Name: "ls", Type: "command", }, Identity: Identity{UserID: "user@ncr.com", EAroles: []string{}}, Target: Target{BannerID: uuid.New().UUID}, }, nil, }, "Fail on missing Command Type": { ValidateCommandPayload{ Command: Command{ Name: "ls", Type: "", }, Identity: Identity{UserID: "user@ncr.com", EAroles: []string{}}, Target: Target{BannerID: uuid.New().UUID}, }, errors.New("command type was empty"), }, "Success on unknown command type": { ValidateCommandPayload{ Command: Command{ Name: "ls", Type: "unknownCommandType", }, Identity: Identity{UserID: "user@ncr.com", EAroles: []string{}}, Target: Target{BannerID: uuid.New().UUID}, }, // We rely on the db to test for known command types nil, }, "Fail no target": { ValidateCommandPayload{ Command: Command{ Name: "ls", Type: "command", }, Identity: Identity{UserID: "user@ncr.com", EAroles: []string{}}, }, ErrInvalidBannerID, }, "Success no UserID": { ValidateCommandPayload{ Command: Command{ Name: "ls", Type: "command", }, Identity: Identity{EAroles: []string{}}, Target: Target{BannerID: uuid.New().UUID}, }, nil, }, "Fail bad target": { ValidateCommandPayload{ Command: Command{ Name: "ls", Type: "command", }, Identity: Identity{UserID: "user@ncr.com", EAroles: []string{}}, Target: Target{BannerID: "not a uuid"}, }, ErrInvalidBannerID, }, "Fail no command": { ValidateCommandPayload{ Identity: Identity{UserID: "user@ncr.com", EAroles: []string{}}, Target: Target{BannerID: uuid.New().UUID}, }, ErrInvalidCommandNil, }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() err := tc.payload.Validate() assert.Equal(t, tc.expectedErr, err) }) } } func TestPostRuleValidation(t *testing.T) { t.Parallel() tests := map[string]struct { rule WriteRule returnError bool }{ "No Errors": { rule: WriteRule{"a", []string{"b"}}, returnError: false, }, "No Errors Multiple entries": { rule: WriteRule{"a", []string{"b", "c"}}, returnError: false, }, "No command": { rule: WriteRule{"", []string{"b"}}, returnError: true, }, "Empty Privilege List": { rule: WriteRule{"a", []string{}}, returnError: true, }, "Empty entry in Privilege List": { rule: WriteRule{"a", []string{""}}, returnError: true, }, "Empty 2nd entry in Privilege List": { rule: WriteRule{"a", []string{"b", ""}}, returnError: true, }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() if tc.returnError { assert.Error(t, tc.rule.Validate()) } else { assert.NoError(t, tc.rule.Validate()) } }) } } func TestPostRulesValidation(t *testing.T) { t.Parallel() tests := map[string]struct { rule WriteRules noErr bool expErr string }{ "Empty list": { rule: WriteRules{}, expErr: "empty rules list", }, "No List": { rule: nil, expErr: "empty rules list", }, "Invalid rule": { rule: WriteRules{WriteRule{}}, expErr: "invalid rule at 0: empty command name", }, "Valid rules": { rule: WriteRules{WriteRule{"a", []string{"b"}}}, noErr: true, }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() err := tc.rule.Validate() if tc.noErr { assert.NoError(t, err) return } assert.EqualError(t, err, tc.expErr) }) } } func TestRuleSetsValidate(t *testing.T) { t.Parallel() tests := map[string]struct { ruleSets RuleSets assertErr assert.ErrorAssertionFunc }{ "Empty rule sets": { ruleSets: RuleSets{}, assertErr: ErrorEqualMsg("empty rules list"), }, "Invalid rule set": { ruleSets: RuleSets{ RuleSet{Privilege: "privilege", Commands: []string{"command1", ""}}, }, assertErr: ErrorEqualMsg("invalid rule at 0: empty command name in array at 1"), }, "Multiple invalid rulesets": { ruleSets: RuleSets{ RuleSet{Privilege: "privilege", Commands: []string{"command1", ""}}, RuleSet{Privilege: "privilege", Commands: []string{"command1", ""}}, }, assertErr: ErrorEqualMsg("invalid rule at 0: empty command name in array at 1\ninvalid rule at 1: empty command name in array at 1"), }, "Valid rule sets": { ruleSets: RuleSets{ RuleSet{Privilege: "privilege1", Commands: []string{"command1", "command2"}}, RuleSet{Privilege: "privilege2", Commands: []string{"command3", "command4"}}, }, assertErr: assert.NoError, }, "Too many rules": { ruleSets: func() RuleSets { ruleSets := make(RuleSets, 501) for i := 0; i < 501; i++ { ruleSets[i] = RuleSet{Privilege: "privilege", Commands: []string{"command"}} } return ruleSets }(), assertErr: ErrorEqualMsg("total number of commands in rules 501 exceeds max 500"), }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() err := tc.ruleSets.Validate() tc.assertErr(t, err) }) } } func TestPostPrivilegePayloadValidate(t *testing.T) { t.Parallel() tests := map[string]struct { payload PostPrivilegePayload assertErr assert.ErrorAssertionFunc }{ "Empty name": { payload: PostPrivilegePayload{Name: ""}, assertErr: ErrorEqualMsg("empty privilege name"), }, "Valid name": { payload: PostPrivilegePayload{Name: "name"}, assertErr: assert.NoError, }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() err := tc.payload.Validate() tc.assertErr(t, err) }) } } func TestPostCommandPayloadValidate(t *testing.T) { t.Parallel() tests := map[string]struct { payload PostCommandPayload assertErr assert.ErrorAssertionFunc }{ "Empty command": { payload: PostCommandPayload{Name: ""}, assertErr: ErrorEqualMsg("empty command name"), }, "Valid command": { payload: PostCommandPayload{Name: "command"}, assertErr: assert.NoError, }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() err := tc.payload.Validate() tc.assertErr(t, err) }) } }