Skip to content

Commit

Permalink
Added tests for Personal Access Token config
Browse files Browse the repository at this point in the history
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
  • Loading branch information
rporres committed Mar 4, 2022
1 parent 1e78c49 commit 25e3a96
Showing 1 changed file with 174 additions and 70 deletions.
244 changes: 174 additions & 70 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,6 @@ func TestLoadFile(t *testing.T) {

}

// returns mandatory receiver fields to be used creating test config structs
// it does not include PAT auth, those tests will be created separately
func mandatoryReceiverFields() []string {
return []string{"Name", "APIURL", "User", "Password", "Project",
"IssueType", "Summary", "ReopenState", "ReopenDuration"}
}

// A test version of the ReceiverConfig struct to create test yaml fixtures
type receiverTestConfig struct {
Name string `yaml:"name,omitempty"`
Expand Down Expand Up @@ -130,93 +123,44 @@ type testConfig struct {
Template string `yaml:"template,omitempty"`
}

// create a receiverTestConfig struct with default values
func newReceiverTestConfig(mandatory []string, optional []string) *receiverTestConfig {
r := receiverTestConfig{}

for _, name := range mandatory {
var value reflect.Value
if name == "APIURL" {
value = reflect.ValueOf("https://jiralert.atlassian.net")
} else if name == "ReopenDuration" {
value = reflect.ValueOf("30d")
} else {
value = reflect.ValueOf(name)
}

reflect.ValueOf(&r).Elem().FieldByName(name).Set(value)
}

for _, name := range optional {
var value reflect.Value
if name == "AddGroupLabels" {
value = reflect.ValueOf(true)
} else {
value = reflect.ValueOf(name)
}

reflect.ValueOf(&r).Elem().FieldByName(name).Set(value)
}

return &r
}

// Required Config keys tests
func TestMissingConfigKeys(t *testing.T) {
defaultsConfig := newReceiverTestConfig(mandatoryReceiverFields(), []string{})
receiverConfig := newReceiverTestConfig([]string{"Name"}, []string{})
template := "jiralert.tmpl"

var config testConfig

// No receivers
config = testConfig{Defaults: defaultsConfig, Receivers: []*receiverTestConfig{}, Template: template}
config = testConfig{Defaults: defaultsConfig, Receivers: []*receiverTestConfig{}, Template: "jiralert.tmpl"}
configErrorTestRunner(t, config, "no receivers defined")

// No template
config = testConfig{Defaults: defaultsConfig, Receivers: []*receiverTestConfig{receiverConfig}}
configErrorTestRunner(t, config, "missing template file")
}

// Creates a yaml from testConfig and checks the errors while loading it
func configErrorTestRunner(t *testing.T, config testConfig, errorMessage string) {
var yamlConfig []byte
var err error

yamlConfig, err = yaml.Marshal(&config)
require.NoError(t, err)

_, err = Load(string(yamlConfig))
require.Error(t, err)
require.Contains(t, err.Error(), errorMessage)
}

// Tests regarding mandatory keys
// No tests for auth keys here. They will be handled separately
func TestRequiredReceiverConfigKeys(t *testing.T) {
type testCase struct {
missingField string
errorMessage string
}

// We'll remove one key at a time and check that the error is the expected one
testTable := []testCase{
{"Name", "missing name for receiver"},
{"APIURL", `missing api_url in receiver "Name"`},
{"User", `missing user in receiver "Name"`},
{"Password", `missing password in receiver "Name"`},
{"Project", `missing project in receiver "Name"`},
{"IssueType", `missing issue_type in receiver "Name"`},
{"Summary", `missing summary in receiver "Name"`},
{"ReopenState", `missing reopen_state in receiver "Name"`},
{"ReopenDuration", `missing reopen_duration in receiver "Name"`},
}

mandatory := mandatoryReceiverFields()
for _, test := range testTable {
var fields []string
for _, value := range mandatoryReceiverFields() {
if value != test.missingField {
fields = append(fields, value)
}
}
fields := removeFromStrSlice(mandatory, test.missingField)

// non-empty defaults as we don't handle the empty defaults case yet
defaultsConfig := newReceiverTestConfig([]string{}, []string{"Priority"})
Expand All @@ -231,7 +175,112 @@ func TestRequiredReceiverConfigKeys(t *testing.T) {

}

// Auth keys error scenarios
func TestAuthKeysErrors(t *testing.T) {
type testCase struct {
receiverTestConfigMandatoryFields []string
errorMessage string
}

mandatory := mandatoryReceiverFields()

// Test cases
// * missing user
// * missing password
// * specifying user/password and PAT auth
testTable := []testCase{
{
removeFromStrSlice(mandatory, "User"),
`missing authentication in receiver "Name"`,
},
{
removeFromStrSlice(mandatory, "Password"),
`missing authentication in receiver "Name"`,
},
{
append(mandatory, "PersonalAccessToken"),
"bad auth config in defaults section: user/password and PAT authentication are mutually exclusive",
},
}

minimalReceiverTestConfig := newReceiverTestConfig([]string{"Name"}, []string{})
for _, test := range testTable {
defaultsConfig := newReceiverTestConfig(test.receiverTestConfigMandatoryFields, []string{})
config := testConfig{
Defaults: defaultsConfig,
Receivers: []*receiverTestConfig{minimalReceiverTestConfig},
Template: "jiralert.tmpl",
}

configErrorTestRunner(t, config, test.errorMessage)
}
}

// These tests want to make sure that receiver auth always overrides defaults auth
func TestAuthKeysOverrides(t *testing.T) {
type testCase struct {
userOverrideValue string
passwordOverrideValue string
patOverrideValue string // Personal Access Token override
defaultFields []string // fields to build the config defaults
}

defaultsWithUserPassword := mandatoryReceiverFields()

defaultsWithPAT := []string{"PersonalAccessToken"}
for _, field := range defaultsWithUserPassword {
if field == "User" || field == "Password" {
continue
}
defaultsWithPAT = append(defaultsWithPAT, field)
}

// Test cases
// * user/password receiver overrides user/password default
// * PAT receiver overrides user/password default
// * PAT receiver overrides PAT default
// * user/password receiver overrides PAT default
testTable := []testCase{
{"jira_user", "jira_password", "", defaultsWithUserPassword},
{"", "", "jira_personal_access_token", defaultsWithUserPassword},
{"jira_user", "jira_password", "", defaultsWithPAT},
{"", "", "jira_personal_access_token", defaultsWithPAT},
}

for _, test := range testTable {
defaultsConfig := newReceiverTestConfig(test.defaultFields, []string{})
receiverConfig := newReceiverTestConfig([]string{"Name"}, []string{})
if test.userOverrideValue != "" {
receiverConfig.User = test.userOverrideValue
}
if test.passwordOverrideValue != "" {
receiverConfig.Password = test.passwordOverrideValue
}
if test.patOverrideValue != "" {
receiverConfig.PersonalAccessToken = test.patOverrideValue
}

config := testConfig{
Defaults: defaultsConfig,
Receivers: []*receiverTestConfig{receiverConfig},
Template: "jiralert.tmpl",
}

yamlConfig, err := yaml.Marshal(&config)
require.NoError(t, err)

cfg, err := Load(string(yamlConfig))
require.NoError(t, err)

receiver := cfg.Receivers[0]
require.Equal(t, receiver.User, test.userOverrideValue)
require.Equal(t, receiver.Password, Secret(test.passwordOverrideValue))
require.Equal(t, receiver.PersonalAccessToken, Secret(test.patOverrideValue))
}
}

// Tests regarding yaml keys overriden in the receiver config
// No tests for auth keys here. They will be handled separately
func TestReceiverOverrides(t *testing.T) {
type testCase struct {
overrideField string
Expand All @@ -242,10 +291,9 @@ func TestReceiverOverrides(t *testing.T) {
fifteenHoursToDuration, err := ParseDuration("15h")
require.NoError(t, err)

// We'll override one key at a time and check the value in the receiver
testTable := []testCase{
{"APIURL", `https://jira.redhat.com`, `https://jira.redhat.com`},
{"User", "jirauser", "jirauser"},
{"Password", "jirapassword", Secret("jirapassword")},
{"Project", "APPSRE", "APPSRE"},
{"IssueType", "Task", "Task"},
{"Summary", "A nice summary", "A nice summary"},
Expand All @@ -271,19 +319,14 @@ func TestReceiverOverrides(t *testing.T) {
Template: "jiralert.tmpl",
}

var yamlConfig []byte
var err error
var cfg *Config

yamlConfig, err = yaml.Marshal(&config)
yamlConfig, err := yaml.Marshal(&config)
require.NoError(t, err)

cfg, err = Load(string(yamlConfig))
cfg, err := Load(string(yamlConfig))
require.NoError(t, err)

receiver := cfg.Receivers[0]
configValue := reflect.ValueOf(receiver).Elem().FieldByName(test.overrideField).Interface()

require.Equal(t, configValue, test.expectedValue)
}

Expand All @@ -292,3 +335,64 @@ func TestReceiverOverrides(t *testing.T) {
// TODO(bwplotka, rporres): Add more tests
// * Tests on optional keys
// * Tests on unknown keys
// * Tests on Duration

// create a receiverTestConfig struct with default values
func newReceiverTestConfig(mandatory []string, optional []string) *receiverTestConfig {
r := receiverTestConfig{}

for _, name := range mandatory {
var value reflect.Value
if name == "APIURL" {
value = reflect.ValueOf("https://jiralert.atlassian.net")
} else if name == "ReopenDuration" {
value = reflect.ValueOf("30d")
} else {
value = reflect.ValueOf(name)
}

reflect.ValueOf(&r).Elem().FieldByName(name).Set(value)
}

for _, name := range optional {
var value reflect.Value
if name == "AddGroupLabels" {
value = reflect.ValueOf(true)
} else {
value = reflect.ValueOf(name)
}

reflect.ValueOf(&r).Elem().FieldByName(name).Set(value)
}

return &r
}

// Creates a yaml from testConfig, Loads it checks the errors are the expected ones
func configErrorTestRunner(t *testing.T, config testConfig, errorMessage string) {
yamlConfig, err := yaml.Marshal(&config)
require.NoError(t, err)

_, err = Load(string(yamlConfig))
require.Error(t, err)
require.Contains(t, err.Error(), errorMessage)
}

// returns a new slice that has the element removed
func removeFromStrSlice(strSlice []string, element string) []string {
var newStrSlice []string
for _, value := range strSlice {
if value != element {
newStrSlice = append(newStrSlice, value)
}
}

return newStrSlice
}

// returns mandatory receiver fields to be used creating test config structs
// it does not include PAT auth, those tests will be created separately
func mandatoryReceiverFields() []string {
return []string{"Name", "APIURL", "User", "Password", "Project",
"IssueType", "Summary", "ReopenState", "ReopenDuration"}
}

0 comments on commit 25e3a96

Please sign in to comment.