gitea-sonarqube-bot/internal/settings/settings_test.go
justusbunsi 685c834b61
Allow pull request naming pattern customization (#28)
Fixes: #3

Signed-off-by: Steven Kriegler <sk.bunsenbrenner@gmail.com>
2022-06-18 14:03:56 +02:00

372 lines
9 KiB
Go

package settings
import (
"io/ioutil"
"os"
"path"
"regexp"
"testing"
"github.com/stretchr/testify/assert"
)
var defaultConfig []byte = []byte(
`gitea:
url: https://example.com/gitea
token:
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
webhook:
secret: haxxor-gitea-secret
sonarqube:
url: https://example.com/sonarqube
token:
value: a09eb5785b25bb2cbacf48808a677a0709f02d8e
webhook:
secret: haxxor-sonarqube-secret
additionalMetrics: []
projects:
- sonarqube:
key: gitea-sonarqube-pr-bot
gitea:
owner: example-organization
name: pr-bot
namingPattern:
regex: "^PR-(\\d+)$"
template: "PR-%d"
`)
func WriteConfigFile(t *testing.T, content []byte) string {
dir := os.TempDir()
config := path.Join(dir, "config.yaml")
t.Cleanup(func() {
os.Remove(config)
})
_ = ioutil.WriteFile(config, content, 0444)
return config
}
func TestLoadWithMissingFile(t *testing.T) {
assert.Panics(t, func() { Load(path.Join(os.TempDir(), "config.yaml")) }, "No panic while reading missing file")
}
func TestLoadWithExistingFile(t *testing.T) {
c := WriteConfigFile(t, defaultConfig)
assert.NotPanics(t, func() { Load(c) }, "Unexpected panic while reading existing file")
}
func TestLoadGiteaStructure(t *testing.T) {
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := GiteaConfig{
Url: "https://example.com/gitea",
Token: &Token{
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
},
Webhook: &Webhook{
Secret: "haxxor-gitea-secret",
},
}
assert.EqualValues(t, expected, Gitea)
}
func TestLoadGiteaStructureInjectedEnvs(t *testing.T) {
os.Setenv("PRBOT_GITEA_WEBHOOK_SECRET", "injected-webhook-secret")
os.Setenv("PRBOT_GITEA_TOKEN_VALUE", "injected-token")
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := GiteaConfig{
Url: "https://example.com/gitea",
Token: &Token{
Value: "injected-token",
},
Webhook: &Webhook{
Secret: "injected-webhook-secret",
},
}
assert.EqualValues(t, expected, Gitea)
t.Cleanup(func() {
os.Unsetenv("PRBOT_GITEA_WEBHOOK_SECRET")
os.Unsetenv("PRBOT_GITEA_TOKEN_VALUE")
})
}
func TestLoadSonarQubeStructure(t *testing.T) {
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := SonarQubeConfig{
Url: "https://example.com/sonarqube",
Token: &Token{
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
},
Webhook: &Webhook{
Secret: "haxxor-sonarqube-secret",
},
}
assert.EqualValues(t, expected, SonarQube)
assert.EqualValues(t, expected.GetMetricsList(), "bugs,vulnerabilities,code_smells")
}
func TestLoadSonarQubeStructureWithAdditionalMetrics(t *testing.T) {
c := WriteConfigFile(t, []byte(
`gitea:
url: https://example.com/gitea
token:
value: fake-gitea-token
sonarqube:
url: https://example.com/sonarqube
token:
value: fake-sonarqube-token
additionalMetrics: "new_security_hotspots"
projects:
- sonarqube:
key: gitea-sonarqube-pr-bot
gitea:
owner: example-organization
name: pr-bot
`))
Load(c)
expected := SonarQubeConfig{
Url: "https://example.com/sonarqube",
Token: &Token{
Value: "fake-sonarqube-token",
},
Webhook: &Webhook{
Secret: "",
},
AdditionalMetrics: []string{
"new_security_hotspots",
},
}
assert.EqualValues(t, expected, SonarQube)
assert.EqualValues(t, expected.AdditionalMetrics, []string{"new_security_hotspots"})
assert.EqualValues(t, "bugs,vulnerabilities,code_smells,new_security_hotspots", SonarQube.GetMetricsList())
}
func TestLoadSonarQubeStructureInjectedEnvs(t *testing.T) {
os.Setenv("PRBOT_SONARQUBE_WEBHOOK_SECRET", "injected-webhook-secret")
os.Setenv("PRBOT_SONARQUBE_TOKEN_VALUE", "injected-token")
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := SonarQubeConfig{
Url: "https://example.com/sonarqube",
Token: &Token{
Value: "injected-token",
},
Webhook: &Webhook{
Secret: "injected-webhook-secret",
},
}
assert.EqualValues(t, expected, SonarQube)
t.Cleanup(func() {
os.Unsetenv("PRBOT_SONARQUBE_WEBHOOK_SECRET")
os.Unsetenv("PRBOT_SONARQUBE_TOKEN_VALUE")
})
}
func TestLoadStructureWithFileReferenceResolving(t *testing.T) {
giteaWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-gitea")
_ = ioutil.WriteFile(giteaWebhookSecretFile, []byte(`gitea-totally-secret`), 0444)
giteaTokenFile := path.Join(os.TempDir(), "token-secret-gitea")
_ = ioutil.WriteFile(giteaTokenFile, []byte(`d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565`), 0444)
sonarqubeWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-sonarqube")
_ = ioutil.WriteFile(sonarqubeWebhookSecretFile, []byte(`sonarqube-totally-secret`), 0444)
sonarqubeTokenFile := path.Join(os.TempDir(), "token-secret-sonarqube")
_ = ioutil.WriteFile(sonarqubeTokenFile, []byte(`a09eb5785b25bb2cbacf48808a677a0709f02d8e`), 0444)
c := WriteConfigFile(t, []byte(
`gitea:
url: https://example.com/gitea
token:
value: fake-gitea-token
sonarqube:
url: https://example.com/sonarqube
token:
value: fake-sonarqube-token
projects:
- sonarqube:
key: gitea-sonarqube-pr-bot
gitea:
owner: example-organization
name: pr-bot
`))
os.Setenv("PRBOT_GITEA_WEBHOOK_SECRETFILE", giteaWebhookSecretFile)
os.Setenv("PRBOT_GITEA_TOKEN_FILE", giteaTokenFile)
os.Setenv("PRBOT_SONARQUBE_WEBHOOK_SECRETFILE", sonarqubeWebhookSecretFile)
os.Setenv("PRBOT_SONARQUBE_TOKEN_FILE", sonarqubeTokenFile)
expectedGitea := GiteaConfig{
Url: "https://example.com/gitea",
Token: &Token{
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
file: giteaTokenFile,
},
Webhook: &Webhook{
Secret: "gitea-totally-secret",
secretFile: giteaWebhookSecretFile,
},
}
expectedSonarQube := SonarQubeConfig{
Url: "https://example.com/sonarqube",
Token: &Token{
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
file: sonarqubeTokenFile,
},
Webhook: &Webhook{
Secret: "sonarqube-totally-secret",
secretFile: sonarqubeWebhookSecretFile,
},
AdditionalMetrics: []string{},
}
Load(c)
assert.EqualValues(t, expectedGitea, Gitea)
assert.EqualValues(t, expectedSonarQube, SonarQube)
t.Cleanup(func() {
os.Remove(giteaWebhookSecretFile)
os.Remove(giteaTokenFile)
os.Remove(sonarqubeWebhookSecretFile)
os.Remove(sonarqubeTokenFile)
os.Unsetenv("PRBOT_GITEA_WEBHOOK_SECRETFILE")
os.Unsetenv("PRBOT_GITEA_TOKEN_FILE")
os.Unsetenv("PRBOT_SONARQUBE_WEBHOOK_SECRETFILE")
os.Unsetenv("PRBOT_SONARQUBE_TOKEN_FILE")
})
}
func TestLoadProjectsStructure(t *testing.T) {
c := WriteConfigFile(t, defaultConfig)
Load(c)
expectedProjects := []Project{
{
SonarQube: struct{ Key string }{
Key: "gitea-sonarqube-pr-bot",
},
Gitea: GiteaRepository{
Owner: "example-organization",
Name: "pr-bot",
},
},
}
assert.EqualValues(t, expectedProjects, Projects)
}
func TestLoadProjectsStructureWithNoMapping(t *testing.T) {
invalidConfig := []byte(
`gitea:
url: https://example.com/gitea
token:
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
webhook:
secret: haxxor-gitea-secret
sonarqube:
url: https://example.com/sonarqube
token:
value: a09eb5785b25bb2cbacf48808a677a0709f02d8e
webhook:
secret: haxxor-sonarqube-secret
projects: []
`)
c := WriteConfigFile(t, invalidConfig)
assert.Panics(t, func() { Load(c) }, "No panic for empty project mapping that is required")
}
func TestLoadNamingPatternStructure(t *testing.T) {
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := &PatternConfig{
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
Template: "PR-%d",
}
assert.EqualValues(t, expected, Pattern)
}
func TestLoadNamingPatternStructureWithInternalDefaults(t *testing.T) {
c := WriteConfigFile(t, []byte(
`gitea:
url: https://example.com/gitea
token:
value: fake-gitea-token
sonarqube:
url: https://example.com/sonarqube
token:
value: fake-sonarqube-token
additionalMetrics: "new_security_hotspots"
projects:
- sonarqube:
key: gitea-sonarqube-pr-bot
gitea:
owner: example-organization
name: pr-bot
`))
Load(c)
expected := &PatternConfig{
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
Template: "PR-%d",
}
assert.EqualValues(t, expected, Pattern)
}
func TestLoadNamingPatternStructureInjectedEnvs(t *testing.T) {
os.Setenv("PRBOT_NAMINGPATTERN_REGEX", "test-(\\d+)-pullrequest")
os.Setenv("PRBOT_NAMINGPATTERN_TEMPLATE", "test-%d-pullrequest")
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := &PatternConfig{
RegExp: regexp.MustCompile(`test-(\d+)-pullrequest`),
Template: "test-%d-pullrequest",
}
assert.EqualValues(t, expected, Pattern)
t.Cleanup(func() {
os.Unsetenv("PRBOT_NAMINGPATTERN_REGEX")
os.Unsetenv("PRBOT_NAMINGPATTERN_TEMPLATE")
})
}
func TestLoadNamingPatternStructureMixedInput(t *testing.T) {
os.Setenv("PRBOT_NAMINGPATTERN_REGEX", "test-(\\d+)-pullrequest")
c := WriteConfigFile(t, defaultConfig)
Load(c)
expected := &PatternConfig{
RegExp: regexp.MustCompile(`test-(\d+)-pullrequest`),
Template: "PR-%d",
}
assert.EqualValues(t, expected, Pattern)
t.Cleanup(func() {
os.Unsetenv("PRBOT_NAMINGPATTERN_REGEX")
})
}