Introduce better test case structure
Signed-off-by: Steven Kriegler <sk.bunsenbrenner@gmail.com>
This commit is contained in:
parent
51211d77cd
commit
54beca9c25
|
@ -6,12 +6,14 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsValidBotCommentForInvalidComment(t *testing.T) {
|
||||
assert.False(t, IsValidBotComment(""), "Undetected missing action prefix")
|
||||
assert.False(t, IsValidBotComment("/sq-bot invalid-command"), "Undetected invalid bot command")
|
||||
assert.False(t, IsValidBotComment("Some context with /sq-bot review within"), "Incorrect bot prefix detected inside random comment")
|
||||
}
|
||||
func TestIsValidBotComment(t *testing.T) {
|
||||
t.Run("Valid", func(t *testing.T) {
|
||||
assert.True(t, IsValidBotComment("/sq-bot review"), "Correct bot comment not recognized")
|
||||
})
|
||||
|
||||
func TestIsValidBotCommentForValidComment(t *testing.T) {
|
||||
assert.True(t, IsValidBotComment("/sq-bot review"), "Correct bot comment not recognized")
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
assert.False(t, IsValidBotComment(""), "Undetected missing action prefix")
|
||||
assert.False(t, IsValidBotComment("/sq-bot invalid-command"), "Undetected invalid bot command")
|
||||
assert.False(t, IsValidBotComment("Some context with /sq-bot review within"), "Incorrect bot prefix detected inside random comment")
|
||||
})
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -93,105 +93,115 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
|
||||
func TestNonAPIRoutes(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
t.Run("favicon", func(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/favicon.ico", nil)
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/favicon.ico", nil)
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusNoContent, w.Code)
|
||||
})
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest("GET", "/ping", nil)
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
t.Run("ping", func(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/ping", nil)
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSonarQubeAPIRouteMissingProjectHeader(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
func TestSonarQubeAPIRoute(t *testing.T) {
|
||||
t.Run("Missing project header", func(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/sonarqube", bytes.NewBuffer([]byte(`{}`)))
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/sonarqube", bytes.NewBuffer([]byte(`{}`)))
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
})
|
||||
|
||||
t.Run("Processing", func(t *testing.T) {
|
||||
sonarQubeHandlerMock := new(SonarQubeHandlerMock)
|
||||
sonarQubeHandlerMock.On("Handle", mock.IsType(&http.Request{}))
|
||||
|
||||
router := New(new(GiteaHandlerMock), sonarQubeHandlerMock)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/sonarqube", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-SonarQube-Project", "gitea-sonarqube-bot")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
sonarQubeHandlerMock.AssertNumberOfCalls(t, "Handle", 1)
|
||||
sonarQubeHandlerMock.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSonarQubeAPIRouteProcessing(t *testing.T) {
|
||||
sonarQubeHandlerMock := new(SonarQubeHandlerMock)
|
||||
sonarQubeHandlerMock.On("Handle", mock.IsType(&http.Request{}))
|
||||
func TestGiteaAPIRoute(t *testing.T) {
|
||||
t.Run("Missing event header", func(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
|
||||
router := New(new(GiteaHandlerMock), sonarQubeHandlerMock)
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/sonarqube", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-SonarQube-Project", "gitea-sonarqube-bot")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
})
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
sonarQubeHandlerMock.AssertNumberOfCalls(t, "Handle", 1)
|
||||
sonarQubeHandlerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestGiteaAPIRouteMissingEventHeader(t *testing.T) {
|
||||
router := New(new(GiteaHandlerMock), new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestGiteaAPIRouteSynchronizeProcessing(t *testing.T) {
|
||||
giteaHandlerMock := new(GiteaHandlerMock)
|
||||
giteaHandlerMock.On("HandleSynchronize", mock.Anything, mock.Anything).Return(nil)
|
||||
giteaHandlerMock.On("HandleComment", mock.Anything, mock.Anything).Maybe()
|
||||
|
||||
router := New(giteaHandlerMock, new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-Gitea-Event", "pull_request")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleSynchronize", 1)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleComment", 0)
|
||||
giteaHandlerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestGiteaAPIRouteCommentProcessing(t *testing.T) {
|
||||
giteaHandlerMock := new(GiteaHandlerMock)
|
||||
giteaHandlerMock.On("HandleSynchronize", mock.Anything, mock.Anything).Maybe()
|
||||
giteaHandlerMock.On("HandleComment", mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
router := New(giteaHandlerMock, new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-Gitea-Event", "issue_comment")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleSynchronize", 0)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleComment", 1)
|
||||
giteaHandlerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestGiteaAPIRouteUnknownEvent(t *testing.T) {
|
||||
giteaHandlerMock := new(GiteaHandlerMock)
|
||||
giteaHandlerMock.On("HandleSynchronize", mock.Anything, mock.Anything).Maybe()
|
||||
giteaHandlerMock.On("HandleComment", mock.Anything, mock.Anything).Maybe()
|
||||
|
||||
router := New(giteaHandlerMock, new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-Gitea-Event", "unknown")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleSynchronize", 0)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleComment", 0)
|
||||
giteaHandlerMock.AssertExpectations(t)
|
||||
t.Run("Processing synchronize", func(t *testing.T) {
|
||||
giteaHandlerMock := new(GiteaHandlerMock)
|
||||
giteaHandlerMock.On("HandleSynchronize", mock.Anything, mock.Anything).Return(nil)
|
||||
giteaHandlerMock.On("HandleComment", mock.Anything, mock.Anything).Maybe()
|
||||
|
||||
router := New(giteaHandlerMock, new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-Gitea-Event", "pull_request")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleSynchronize", 1)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleComment", 0)
|
||||
giteaHandlerMock.AssertExpectations(t)
|
||||
})
|
||||
|
||||
t.Run("Processing comment", func(t *testing.T) {
|
||||
giteaHandlerMock := new(GiteaHandlerMock)
|
||||
giteaHandlerMock.On("HandleSynchronize", mock.Anything, mock.Anything).Maybe()
|
||||
giteaHandlerMock.On("HandleComment", mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
router := New(giteaHandlerMock, new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-Gitea-Event", "issue_comment")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleSynchronize", 0)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleComment", 1)
|
||||
giteaHandlerMock.AssertExpectations(t)
|
||||
})
|
||||
|
||||
t.Run("Unknown event", func(t *testing.T) {
|
||||
giteaHandlerMock := new(GiteaHandlerMock)
|
||||
giteaHandlerMock.On("HandleSynchronize", mock.Anything, mock.Anything).Maybe()
|
||||
giteaHandlerMock.On("HandleComment", mock.Anything, mock.Anything).Maybe()
|
||||
|
||||
router := New(giteaHandlerMock, new(SonarQubeHandlerMock))
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/hooks/gitea", bytes.NewBuffer([]byte(`{}`)))
|
||||
req.Header.Add("X-Gitea-Event", "unknown")
|
||||
router.Engine.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleSynchronize", 0)
|
||||
giteaHandlerMock.AssertNumberOfCalls(t, "HandleComment", 0)
|
||||
giteaHandlerMock.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,37 +10,38 @@ func getRequestData() []byte {
|
|||
return []byte(`{"serverUrl":"https://example.com","status":"SUCCESS","analysedAt":"2022-05-15T16:45:31+0000","revision":"378080777919s07657a07f7a3e2d05dc75f64edd","changedAt":"2022-05-15T16:41:39+0000","project":{"key":"gitea-sonarqube-bot","name":"Gitea SonarQube Bot","url":"https://example.com/dashboard?id=gitea-sonarqube-bot"},"branch":{"name":"PR-1822","type":"PULL_REQUEST","isMain":false,"url":"https://example.com/dashboard?id=gitea-sonarqube-bot&pullRequest=PR-1822"},"qualityGate":{"name":"GiteaSonarQubeBot","status":"OK","conditions":[{"metric":"new_reliability_rating","operator":"GREATER_THAN","value":"1","status":"OK","errorThreshold":"1"},{"metric":"new_security_rating","operator":"GREATER_THAN","value":"1","status":"OK","errorThreshold":"1"},{"metric":"new_maintainability_rating","operator":"GREATER_THAN","value":"1","status":"OK","errorThreshold":"1"},{"metric":"new_security_hotspots_reviewed","operator":"LESS_THAN","status":"OK","errorThreshold":"100"}]},"properties":{"sonar.analysis.sqbot":"378080777919s07657a07f7a3e2d05dc75f64edd"}}`)
|
||||
}
|
||||
|
||||
func TestIsValidWebhookSuccess(t *testing.T) {
|
||||
actual, _ := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "647f2395d30b1b7efcb58d9338be5b69c2addb54faf6bde6314a57ea28f45467", "test-component")
|
||||
assert.True(t, actual, "Expected successful webhook signature validation")
|
||||
}
|
||||
func TestIsValidWebhook(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
actual, _ := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "647f2395d30b1b7efcb58d9338be5b69c2addb54faf6bde6314a57ea28f45467", "test-component")
|
||||
assert.True(t, actual, "Expected successful webhook signature validation")
|
||||
})
|
||||
|
||||
func TestIsValidWebhookNothingConfiguredOrProvidedSuccess(t *testing.T) {
|
||||
actual, _ := isValidWebhook(getRequestData(), "", "", "test-component")
|
||||
assert.True(t, actual, "Webhook signature validation not skipped")
|
||||
}
|
||||
t.Run("Nothing configured or provided", func(t *testing.T) {
|
||||
actual, _ := isValidWebhook(getRequestData(), "", "", "test-component")
|
||||
assert.True(t, actual, "Webhook signature validation not skipped")
|
||||
})
|
||||
|
||||
func TestIsValidWebhookSignatureDecodingFailure(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "invalid-signature", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "Error decoding signature for test-component webhook.", "Undetected signature encoding error")
|
||||
}
|
||||
t.Run("Signature decoding error", func(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "invalid-signature", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "Error decoding signature for test-component webhook.", "Undetected signature encoding error")
|
||||
})
|
||||
|
||||
func TestIsValidWebhookSignatureMismatchFailure(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "fde6a666b7a1a46c27efb1961c17b46b6cf7aa13db5560e5ac95e801a18a92f3", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "Signature header does not match the received test-component webhook content. Request rejected.", "Undetected signature mismatch")
|
||||
// assert.EqualError(t, err, "Signature header received but no test-component webhook secret configured. Request rejected due to possible configuration mismatch.", "Undetected configuration mismatch (1)")
|
||||
}
|
||||
t.Run("Signature mismatch", func(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "fde6a666b7a1a46c27efb1961c17b46b6cf7aa13db5560e5ac95e801a18a92f3", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "Signature header does not match the received test-component webhook content. Request rejected.", "Undetected signature mismatch")
|
||||
})
|
||||
|
||||
func TestIsValidWebhookEmptySecretConfigurationFailure(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "", "647f2395d30b1b7efcb58d9338be5b69c2addb54faf6bde6314a57ea28f45467", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "Signature header received but no test-component webhook secret configured. Request rejected due to possible configuration mismatch.", "Undetected configuration mismatch (1)")
|
||||
}
|
||||
t.Run("Empty secret configuration", func(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "", "647f2395d30b1b7efcb58d9338be5b69c2addb54faf6bde6314a57ea28f45467", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "Signature header received but no test-component webhook secret configured. Request rejected due to possible configuration mismatch.", "Undetected configuration mismatch (1)")
|
||||
})
|
||||
|
||||
func TestIsValidWebhookEmptySignatureConfigurationFailure(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "test-component webhook secret configured but no signature header received. Request rejected due to possible configuration mismatch.", "Undetected configuration mismatch (2)")
|
||||
t.Run("Empty signature configuration", func(t *testing.T) {
|
||||
actual, err := isValidWebhook(getRequestData(), "sonarqube-test-webhook-secret", "", "test-component")
|
||||
assert.False(t, actual)
|
||||
assert.EqualError(t, err, "test-component webhook secret configured but no signature header received. Request rejected due to possible configuration mismatch.", "Undetected configuration mismatch (2)")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -34,137 +34,139 @@ func withValidSonarQubeRequestData(t *testing.T, jsonBody []byte) (*http.Request
|
|||
return req, rr, handler
|
||||
}
|
||||
|
||||
func TestHandleSonarQubeWebhookProjectMapped(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
func TestHandleSonarQubeWebhook(t *testing.T) {
|
||||
t.Run("With mapped Project", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Processing data. See bot logs for details."}`, rr.Body.String())
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Processing data. See bot logs for details."}`, rr.Body.String())
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestHandleSonarQubeWebhookProjectNotMapped(t *testing.T) {
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "another-project",
|
||||
},
|
||||
},
|
||||
}
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Project 'pr-bot' not in configured list. Request ignored."}`, rr.Body.String())
|
||||
}
|
||||
|
||||
func TestHandleSonarQubeWebhookInvalidJSONBody(t *testing.T) {
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": ["invalid-server-url-content"] }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusUnprocessableEntity, rr.Code)
|
||||
assert.Equal(t, `{"message": "Error parsing POST body."}`, rr.Body.String())
|
||||
}
|
||||
|
||||
func TestHandleSonarQubeWebhookInvalidWebhookSignature(t *testing.T) {
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "sonarqube-test-webhook-secret",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
req.Header.Set("X-Sonar-Webhook-HMAC-SHA256", "647f2395d30b1b7efcb58d9338be5b69c2addb54faf6bde6314a57ea28f45467")
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusPreconditionFailed, rr.Code)
|
||||
assert.Equal(t, `{"message": "Webhook validation failed. Request rejected."}`, rr.Body.String())
|
||||
}
|
||||
|
||||
func TestHandleSonarQubeWebhookForPullRequest(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Processing data. See bot logs for details."}`, rr.Body.String())
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestHandleSonarQubeWebhookForBranch(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "BRANCH", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Ignore Hook for non-PR analysis."}`, rr.Body.String())
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Without mapped project", func(t *testing.T) {
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "another-project",
|
||||
},
|
||||
},
|
||||
}
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Project 'pr-bot' not in configured list. Request ignored."}`, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("With invalid JSON body", func(t *testing.T) {
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": ["invalid-server-url-content"] }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusUnprocessableEntity, rr.Code)
|
||||
assert.Equal(t, `{"message": "Error parsing POST body."}`, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("With invalid webhook signature", func(t *testing.T) {
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "sonarqube-test-webhook-secret",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
req.Header.Set("X-Sonar-Webhook-HMAC-SHA256", "647f2395d30b1b7efcb58d9338be5b69c2addb54faf6bde6314a57ea28f45467")
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusPreconditionFailed, rr.Code)
|
||||
assert.Equal(t, `{"message": "Webhook validation failed. Request rejected."}`, rr.Body.String())
|
||||
})
|
||||
|
||||
t.Run("Running for Pull Request", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Processing data. See bot logs for details."}`, rr.Body.String())
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Running for branch", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
settings.SonarQube = settings.SonarQubeConfig{
|
||||
Webhook: &settings.Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
}
|
||||
settings.Projects = []settings.Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
req, rr, handler := withValidSonarQubeRequestData(t, []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "BRANCH", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`))
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Equal(t, `{"message": "Ignore Hook for non-PR analysis."}`, rr.Body.String())
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -28,29 +28,31 @@ func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
|
|||
}, c.responseError
|
||||
}
|
||||
|
||||
func TestParsePRIndexSuccess(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
func TestParsePRIndex(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
|
||||
actual, _ := ParsePRIndex("PR-1337")
|
||||
assert.Equal(t, 1337, actual, "PR index parsing is broken")
|
||||
actual, _ := ParsePRIndex("PR-1337")
|
||||
assert.Equal(t, 1337, actual, "PR index parsing is broken")
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestParsePRIndexNonIntegerFailure(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
t.Run("No integer value", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
|
||||
_, err := ParsePRIndex("PR-invalid")
|
||||
assert.EqualErrorf(t, err, "branch name 'PR-invalid' does not match regex '^PR-(\\d+)$'", "Integer parsing succeeds unexpectedly")
|
||||
_, err := ParsePRIndex("PR-invalid")
|
||||
assert.EqualErrorf(t, err, "branch name 'PR-invalid' does not match regex '^PR-(\\d+)$'", "Integer parsing succeeds unexpectedly")
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -66,16 +68,14 @@ func TestPRNameFromIndex(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestGetRenderedQualityGateSuccess(t *testing.T) {
|
||||
actual := GetRenderedQualityGate("OK")
|
||||
func TestGetRenderedQualityGate(t *testing.T) {
|
||||
t.Run("Passed", func(t *testing.T) {
|
||||
assert.Contains(t, GetRenderedQualityGate("OK"), ":white_check_mark:", "Undetected successful quality gate during status rendering")
|
||||
})
|
||||
|
||||
assert.Contains(t, actual, ":white_check_mark:", "Undetected successful quality gate during status rendering")
|
||||
}
|
||||
|
||||
func TestGetRenderedQualityGateFailure(t *testing.T) {
|
||||
actual := GetRenderedQualityGate("ERROR")
|
||||
|
||||
assert.Contains(t, actual, ":x:", "Undetected failed quality gate during status rendering")
|
||||
t.Run("Failed", func(t *testing.T) {
|
||||
assert.Contains(t, GetRenderedQualityGate("ERROR"), ":x:", "Undetected failed quality gate during status rendering")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetPullRequestUrl(t *testing.T) {
|
||||
|
@ -94,435 +94,445 @@ func TestGetPullRequestUrl(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRetrieveDataFromApiSuccess(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
func TestRetrieveDataFromApi(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
wrapper := &PullsResponse{}
|
||||
err := retrieveDataFromApi(sdk, request, wrapper)
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.Equal(t, "Basic dGVzdC10b2tlbjo=", request.Header.Get("Authorization"), "Authorization header not set")
|
||||
assert.Equal(t, "PR-1", wrapper.PullRequests[0].Key, "Unmarshallowing into wrapper broken")
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
wrapper := &PullsResponse{}
|
||||
err := retrieveDataFromApi(sdk, request, wrapper)
|
||||
t.Run("Internal error", func(t *testing.T) {
|
||||
expected := fmt.Errorf("This error indicates an error while performing the request")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}),
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.Equal(t, "Basic dGVzdC10b2tlbjo=", request.Header.Get("Authorization"), "Authorization header not set")
|
||||
assert.Equal(t, "PR-1", wrapper.PullRequests[0].Key, "Unmarshallowing into wrapper broken")
|
||||
}
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
|
||||
func TestRetrieveDataFromApiRequestError(t *testing.T) {
|
||||
expected := fmt.Errorf("This error indicates an error while performing the request")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}),
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
|
||||
assert.ErrorIs(t, err, expected, "Undetected request performing error")
|
||||
}
|
||||
|
||||
func TestRetrieveDataFromApiUnauthorized(t *testing.T) {
|
||||
recorder := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
recorder.Code = http.StatusUnauthorized
|
||||
assert.ErrorIs(t, err, expected, "Undetected request performing error")
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "simulated-invalid-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: recorder,
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
t.Run("Unauthorized", func(t *testing.T) {
|
||||
recorder := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
recorder.Code = http.StatusUnauthorized
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "simulated-invalid-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: recorder,
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
assert.Errorf(t, err, "missing or invalid API token", "Undetected unauthorized error")
|
||||
}
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
|
||||
func TestRetrieveDataFromApiBodyReadError(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
assert.Errorf(t, err, "missing or invalid API token", "Undetected unauthorized error")
|
||||
})
|
||||
expected := fmt.Errorf("Error reading body content")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: func(r io.Reader) ([]byte, error) {
|
||||
return []byte(``), expected
|
||||
},
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
t.Run("Body read error", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Error reading body content")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: func(r io.Reader) ([]byte, error) {
|
||||
return []byte(``), expected
|
||||
},
|
||||
}
|
||||
|
||||
assert.ErrorIs(t, err, expected, "Undetected body processing error")
|
||||
}
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
|
||||
func TestRetrieveDataFromApiBodyUnmarshalError(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullReq`))
|
||||
assert.ErrorIs(t, err, expected, "Undetected body processing error")
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
t.Run("Unmarshal error", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullReq`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
}
|
||||
|
||||
assert.Errorf(t, err, "unexpected end of JSON input", "Undetected body unmarshal error")
|
||||
}
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
|
||||
err := retrieveDataFromApi(sdk, request, &PullsResponse{})
|
||||
|
||||
func TestFetchPullRequestsSuccess(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.IsType(t, &PullsResponse{}, actual, "Happy path broken")
|
||||
}
|
||||
|
||||
func TestFetchPullRequestsRequestBuildingFailure(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
assert.Equal(t, expected, err, "Unexpected error instance returned")
|
||||
}
|
||||
|
||||
func TestFetchPullRequestsRequestError(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
assert.Equal(t, expected, err)
|
||||
}
|
||||
|
||||
func TestFetchPullRequestsErrorsInResponse(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"errors":[{"msg":"Project 'test-project' not found"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
assert.Errorf(t, err, "Project 'test-project' not found", "Response error parsing broken")
|
||||
}
|
||||
|
||||
func TestGetPullRequestSuccess(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
Template: "PR-%d",
|
||||
}
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.GetPullRequest("test-project", 1)
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.IsType(t, &PullRequest{}, actual, "Happy path broken")
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
assert.Errorf(t, err, "unexpected end of JSON input", "Undetected body unmarshal error")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetPullRequestFetchError(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
func TestFetchPullRequests(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.IsType(t, &PullsResponse{}, actual, "Happy path broken")
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetPullRequest("test-project", 1)
|
||||
t.Run("Building failure", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
|
||||
assert.Errorf(t, err, "fetching pull requests failed", "Incorrect edge case is throwing errors")
|
||||
assert.Errorf(t, err, "Some simulated error", "Unexpected error cause")
|
||||
}
|
||||
_, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
func TestGetPullRequestUnknownPR(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
Template: "PR-%d",
|
||||
}
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
assert.Equal(t, expected, err, "Unexpected error instance returned")
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetPullRequest("test-project", 1337)
|
||||
t.Run("Internal error", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
assert.Errorf(t, err, "no pull request found with name 'PR-1337'")
|
||||
_, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
assert.Equal(t, expected, err)
|
||||
})
|
||||
|
||||
t.Run("Errors in response", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"errors":[{"msg":"Project 'test-project' not found"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.fetchPullRequests("test-project")
|
||||
|
||||
assert.Errorf(t, err, "Project 'test-project' not found", "Response error parsing broken")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetMeasuresSuccess(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"0","bestValue":true}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
func TestGetPullRequest(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
Template: "PR-%d",
|
||||
}
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.GetPullRequest("test-project", 1)
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.IsType(t, &PullRequest{}, actual, "Happy path broken")
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.GetMeasures("test-project", "PR-1")
|
||||
t.Run("Fetch error", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.IsType(t, &MeasuresResponse{}, actual, "Happy path broken")
|
||||
_, err := sdk.GetPullRequest("test-project", 1)
|
||||
|
||||
assert.Errorf(t, err, "fetching pull requests failed", "Incorrect edge case is throwing errors")
|
||||
assert.Errorf(t, err, "Some simulated error", "Unexpected error cause")
|
||||
})
|
||||
|
||||
t.Run("Unknown PR", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
Template: "PR-%d",
|
||||
}
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"pullRequests":[{"key":"PR-1","title":"pr-branch","branch":"pr-branch","base":"main","status":{"qualityGateStatus":"OK","bugs":0,"vulnerabilities":0,"codeSmells":0},"analysisDate":"2022-06-12T11:23:09+0000","target":"main"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetPullRequest("test-project", 1337)
|
||||
|
||||
assert.Errorf(t, err, "no pull request found with name 'PR-1337'")
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetMeasuresRequestBuildingFailure(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"0","bestValue":true}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
func TestGetMeasures(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"0","bestValue":true}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.GetMeasures("test-project", "PR-1")
|
||||
|
||||
assert.Nil(t, err, "Successful data retrieval broken and throws error")
|
||||
assert.IsType(t, &MeasuresResponse{}, actual, "Happy path broken")
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetMeasures("test-project", "PR-1")
|
||||
t.Run("Building failure", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"0","bestValue":true}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
|
||||
assert.Equal(t, expected, err, "Unexpected error instance returned")
|
||||
_, err := sdk.GetMeasures("test-project", "PR-1")
|
||||
|
||||
assert.Equal(t, expected, err, "Unexpected error instance returned")
|
||||
})
|
||||
|
||||
t.Run("Request error", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"0","bestValue":true}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetMeasures("test-project", "PR-1")
|
||||
|
||||
assert.Equal(t, expected, err)
|
||||
})
|
||||
|
||||
t.Run("Errors in response", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"errors":[{"msg":"Component 'non-existing-project' of pull request 'PR-1' not found"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetMeasures("non-existing-project", "PR-1")
|
||||
|
||||
assert.Errorf(t, err, "Component 'non-existing-project' of pull request 'PR-1' not found", "Response error parsing broken")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetMeasuresRequestError(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"0","bestValue":true}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Some simulated error")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: expected,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
func TestComposeGiteaComment(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"10","bestValue":false}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetMeasures("test-project", "PR-1")
|
||||
actual, err := sdk.ComposeGiteaComment(&CommentComposeData{
|
||||
Key: "test-project",
|
||||
PRName: "PR-1",
|
||||
Url: "https://sonarqube.example.com",
|
||||
QualityGate: "OK",
|
||||
})
|
||||
|
||||
assert.Equal(t, expected, err)
|
||||
}
|
||||
|
||||
func TestGetMeasuresErrorsInResponse(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"errors":[{"msg":"Component 'non-existing-project' of pull request 'PR-1' not found"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.GetMeasures("non-existing-project", "PR-1")
|
||||
|
||||
assert.Errorf(t, err, "Component 'non-existing-project' of pull request 'PR-1' not found", "Response error parsing broken")
|
||||
}
|
||||
|
||||
func TestComposeGiteaCommentSuccess(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"10","bestValue":false}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return httptest.NewRequest(method, target, body), nil
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := sdk.ComposeGiteaComment(&CommentComposeData{
|
||||
Key: "test-project",
|
||||
PRName: "PR-1",
|
||||
Url: "https://sonarqube.example.com",
|
||||
QualityGate: "OK",
|
||||
assert.Nil(t, err, "Successful comment composing throwing errors")
|
||||
assert.Contains(t, actual, ":white_check_mark:", "Happy path [Quality Gate] broken")
|
||||
assert.Contains(t, actual, "| Metric | Current |", "Happy path [Metrics Header] broken")
|
||||
assert.Contains(t, actual, "| Bugs | 10 |", "Happy path [Metrics Values] broken")
|
||||
assert.Contains(t, actual, "https://sonarqube.example.com", "Happy path [Link] broken")
|
||||
assert.Contains(t, actual, "/sq-bot review", "Happy path [Command] broken")
|
||||
})
|
||||
|
||||
assert.Nil(t, err, "Successful comment composing throwing errors")
|
||||
assert.Contains(t, actual, ":white_check_mark:", "Happy path [Quality Gate] broken")
|
||||
assert.Contains(t, actual, "| Metric | Current |", "Happy path [Metrics Header] broken")
|
||||
assert.Contains(t, actual, "| Bugs | 10 |", "Happy path [Metrics Values] broken")
|
||||
assert.Contains(t, actual, "https://sonarqube.example.com", "Happy path [Link] broken")
|
||||
assert.Contains(t, actual, "/sq-bot review", "Happy path [Command] broken")
|
||||
}
|
||||
t.Run("Error", func(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"10","bestValue":false}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
})
|
||||
expected := fmt.Errorf("Expected error from GetMeasures")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
|
||||
func TestComposeGiteaCommentError(t *testing.T) {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"component":{"key":"test-project","name":"Test Project","qualifier":"TRK","measures":[{"metric":"bugs","value":"10","bestValue":false}],"pullRequest":"PR-1"},"metrics":[{"key":"bugs","name":"Bugs","description":"Bugs","domain":"Reliability","type":"INT","higherValuesAreBetter":false,"qualitative":false,"hidden":false,"custom":false,"bestValue":"0"}]}`))
|
||||
_, err := sdk.ComposeGiteaComment(&CommentComposeData{
|
||||
Key: "test-project",
|
||||
PRName: "PR-1",
|
||||
Url: "https://sonarqube.example.com",
|
||||
QualityGate: "OK",
|
||||
})
|
||||
|
||||
assert.Errorf(t, err, expected.Error(), "Undetected error while composing comment")
|
||||
})
|
||||
expected := fmt.Errorf("Expected error from GetMeasures")
|
||||
sdk := &SonarQubeSdk{
|
||||
token: "test-token",
|
||||
client: &ClientMock{
|
||||
handler: handler,
|
||||
recoder: httptest.NewRecorder(),
|
||||
responseError: nil,
|
||||
},
|
||||
bodyReader: io.ReadAll,
|
||||
httpRequest: func(method, target string, body io.Reader) (*http.Request, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
|
||||
_, err := sdk.ComposeGiteaComment(&CommentComposeData{
|
||||
Key: "test-project",
|
||||
PRName: "PR-1",
|
||||
Url: "https://sonarqube.example.com",
|
||||
QualityGate: "OK",
|
||||
})
|
||||
|
||||
assert.Errorf(t, err, expected.Error(), "Undetected error while composing comment")
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
|
|
|
@ -10,8 +10,9 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var defaultConfig []byte = []byte(
|
||||
`gitea:
|
||||
func defaultConfig() []byte {
|
||||
return []byte(
|
||||
`gitea:
|
||||
url: https://example.com/gitea
|
||||
token:
|
||||
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
||||
|
@ -34,6 +35,7 @@ namingPattern:
|
|||
regex: "^PR-(\\d+)$"
|
||||
template: "PR-%d"
|
||||
`)
|
||||
}
|
||||
|
||||
func WriteConfigFile(t *testing.T, content []byte) string {
|
||||
dir := os.TempDir()
|
||||
|
@ -48,78 +50,157 @@ func WriteConfigFile(t *testing.T, content []byte) string {
|
|||
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 TestLoad(t *testing.T) {
|
||||
t.Run("Missing file", func(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)
|
||||
t.Run("Existing file", func(t *testing.T) {
|
||||
c := WriteConfigFile(t, defaultConfig())
|
||||
assert.NotPanics(t, func() { Load(c) }, "Unexpected panic while reading existing file")
|
||||
})
|
||||
|
||||
assert.NotPanics(t, func() { Load(c) }, "Unexpected panic while reading existing file")
|
||||
}
|
||||
t.Run("File references", func(t *testing.T) {
|
||||
giteaWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-gitea")
|
||||
_ = ioutil.WriteFile(giteaWebhookSecretFile, []byte(`gitea-totally-secret`), 0444)
|
||||
|
||||
func TestLoadGiteaStructure(t *testing.T) {
|
||||
c := WriteConfigFile(t, defaultConfig)
|
||||
Load(c)
|
||||
giteaTokenFile := path.Join(os.TempDir(), "token-secret-gitea")
|
||||
_ = ioutil.WriteFile(giteaTokenFile, []byte(`d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565`), 0444)
|
||||
|
||||
expected := GiteaConfig{
|
||||
Url: "https://example.com/gitea",
|
||||
Token: &Token{
|
||||
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "haxxor-gitea-secret",
|
||||
},
|
||||
}
|
||||
sonarqubeWebhookSecretFile := path.Join(os.TempDir(), "webhook-secret-sonarqube")
|
||||
_ = ioutil.WriteFile(sonarqubeWebhookSecretFile, []byte(`sonarqube-totally-secret`), 0444)
|
||||
|
||||
assert.EqualValues(t, expected, Gitea)
|
||||
}
|
||||
sonarqubeTokenFile := path.Join(os.TempDir(), "token-secret-sonarqube")
|
||||
_ = ioutil.WriteFile(sonarqubeTokenFile, []byte(`a09eb5785b25bb2cbacf48808a677a0709f02d8e`), 0444)
|
||||
|
||||
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)
|
||||
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-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)
|
||||
|
||||
expected := GiteaConfig{
|
||||
Url: "https://example.com/gitea",
|
||||
Token: &Token{
|
||||
Value: "injected-token",
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "injected-webhook-secret",
|
||||
},
|
||||
}
|
||||
expectedGitea := GiteaConfig{
|
||||
Url: "https://example.com/gitea",
|
||||
Token: &Token{
|
||||
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
||||
file: giteaTokenFile,
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "gitea-totally-secret",
|
||||
secretFile: giteaWebhookSecretFile,
|
||||
},
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, Gitea)
|
||||
expectedSonarQube := SonarQubeConfig{
|
||||
Url: "https://example.com/sonarqube",
|
||||
Token: &Token{
|
||||
Value: "a09eb5785b25bb2cbacf48808a677a0709f02d8e",
|
||||
file: sonarqubeTokenFile,
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "sonarqube-totally-secret",
|
||||
secretFile: sonarqubeWebhookSecretFile,
|
||||
},
|
||||
AdditionalMetrics: []string{},
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("PRBOT_GITEA_WEBHOOK_SECRET")
|
||||
os.Unsetenv("PRBOT_GITEA_TOKEN_VALUE")
|
||||
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 TestLoadSonarQubeStructure(t *testing.T) {
|
||||
c := WriteConfigFile(t, defaultConfig)
|
||||
Load(c)
|
||||
func TestLoadGitea(t *testing.T) {
|
||||
t.Run("Default", func(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",
|
||||
},
|
||||
}
|
||||
expected := GiteaConfig{
|
||||
Url: "https://example.com/gitea",
|
||||
Token: &Token{
|
||||
Value: "d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565",
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "haxxor-gitea-secret",
|
||||
},
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, SonarQube)
|
||||
assert.EqualValues(t, expected.GetMetricsList(), "bugs,vulnerabilities,code_smells")
|
||||
assert.EqualValues(t, expected, Gitea)
|
||||
})
|
||||
|
||||
t.Run("Injected envs", func(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 TestLoadSonarQubeStructureWithAdditionalMetrics(t *testing.T) {
|
||||
c := WriteConfigFile(t, []byte(
|
||||
`gitea:
|
||||
func TestLoadSonarQube(t *testing.T) {
|
||||
t.Run("Default", func(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")
|
||||
})
|
||||
|
||||
t.Run("Additional metrics", func(t *testing.T) {
|
||||
c := WriteConfigFile(t, []byte(
|
||||
`gitea:
|
||||
url: https://example.com/gitea
|
||||
token:
|
||||
value: fake-gitea-token
|
||||
|
@ -135,147 +216,74 @@ projects:
|
|||
owner: example-organization
|
||||
name: pr-bot
|
||||
`))
|
||||
Load(c)
|
||||
Load(c)
|
||||
|
||||
expected := SonarQubeConfig{
|
||||
Url: "https://example.com/sonarqube",
|
||||
Token: &Token{
|
||||
Value: "fake-sonarqube-token",
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "",
|
||||
},
|
||||
AdditionalMetrics: []string{
|
||||
"new_security_hotspots",
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
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)
|
||||
t.Run("Injected envs", func(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",
|
||||
},
|
||||
}
|
||||
expected := SonarQubeConfig{
|
||||
Url: "https://example.com/sonarqube",
|
||||
Token: &Token{
|
||||
Value: "injected-token",
|
||||
},
|
||||
Webhook: &Webhook{
|
||||
Secret: "injected-webhook-secret",
|
||||
},
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, SonarQube)
|
||||
assert.EqualValues(t, expected, SonarQube)
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("PRBOT_SONARQUBE_WEBHOOK_SECRET")
|
||||
os.Unsetenv("PRBOT_SONARQUBE_TOKEN_VALUE")
|
||||
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)
|
||||
func TestLoadProjects(t *testing.T) {
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
c := WriteConfigFile(t, defaultConfig())
|
||||
Load(c)
|
||||
|
||||
giteaTokenFile := path.Join(os.TempDir(), "token-secret-gitea")
|
||||
_ = ioutil.WriteFile(giteaTokenFile, []byte(`d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565`), 0444)
|
||||
expectedProjects := []Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "gitea-sonarqube-bot",
|
||||
},
|
||||
Gitea: GiteaRepository{
|
||||
Owner: "example-organization",
|
||||
Name: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
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-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")
|
||||
assert.EqualValues(t, expectedProjects, Projects)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoadProjectsStructure(t *testing.T) {
|
||||
c := WriteConfigFile(t, defaultConfig)
|
||||
Load(c)
|
||||
|
||||
expectedProjects := []Project{
|
||||
{
|
||||
SonarQube: struct{ Key string }{
|
||||
Key: "gitea-sonarqube-bot",
|
||||
},
|
||||
Gitea: GiteaRepository{
|
||||
Owner: "example-organization",
|
||||
Name: "pr-bot",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expectedProjects, Projects)
|
||||
}
|
||||
|
||||
func TestLoadProjectsStructureWithNoMapping(t *testing.T) {
|
||||
invalidConfig := []byte(
|
||||
`gitea:
|
||||
t.Run("Empty mapping", func(t *testing.T) {
|
||||
invalidConfig := []byte(
|
||||
`gitea:
|
||||
url: https://example.com/gitea
|
||||
token:
|
||||
value: d0fcdeb5eaa99c506831f9eb4e63fc7cc484a565
|
||||
|
@ -289,26 +297,28 @@ sonarqube:
|
|||
secret: haxxor-sonarqube-secret
|
||||
projects: []
|
||||
`)
|
||||
c := WriteConfigFile(t, invalidConfig)
|
||||
c := WriteConfigFile(t, invalidConfig)
|
||||
|
||||
assert.Panics(t, func() { Load(c) }, "No panic for empty project mapping that is required")
|
||||
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)
|
||||
func TestLoadNamingPattern(t *testing.T) {
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
c := WriteConfigFile(t, defaultConfig())
|
||||
Load(c)
|
||||
|
||||
expected := &PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
Template: "PR-%d",
|
||||
}
|
||||
expected := &PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
Template: "PR-%d",
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, Pattern)
|
||||
}
|
||||
assert.EqualValues(t, expected, Pattern)
|
||||
})
|
||||
|
||||
func TestLoadNamingPatternStructureWithInternalDefaults(t *testing.T) {
|
||||
c := WriteConfigFile(t, []byte(
|
||||
`gitea:
|
||||
t.Run("Internal defaults", func(t *testing.T) {
|
||||
c := WriteConfigFile(t, []byte(
|
||||
`gitea:
|
||||
url: https://example.com/gitea
|
||||
token:
|
||||
value: fake-gitea-token
|
||||
|
@ -324,48 +334,49 @@ projects:
|
|||
owner: example-organization
|
||||
name: pr-bot
|
||||
`))
|
||||
Load(c)
|
||||
Load(c)
|
||||
|
||||
expected := &PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
Template: "PR-%d",
|
||||
}
|
||||
expected := &PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
Template: "PR-%d",
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, Pattern)
|
||||
}
|
||||
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)
|
||||
t.Run("Injected envs", func(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",
|
||||
}
|
||||
expected := &PatternConfig{
|
||||
RegExp: regexp.MustCompile(`test-(\d+)-pullrequest`),
|
||||
Template: "test-%d-pullrequest",
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, Pattern)
|
||||
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")
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("PRBOT_NAMINGPATTERN_REGEX")
|
||||
os.Unsetenv("PRBOT_NAMINGPATTERN_TEMPLATE")
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Mixed input", func(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")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,47 +10,49 @@ import (
|
|||
)
|
||||
|
||||
func TestNewWebhook(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
|
||||
raw := []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": { "sonar.analysis.sqbot": "a84442009c09b1adc278b6bb80a3853419f54007" } }`)
|
||||
response, ok := New(raw)
|
||||
raw := []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "PR-1337", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": { "sonar.analysis.sqbot": "a84442009c09b1adc278b6bb80a3853419f54007" } }`)
|
||||
response, ok := New(raw)
|
||||
|
||||
assert.NotNil(t, response)
|
||||
assert.Equal(t, 1337, response.PRIndex)
|
||||
assert.Equal(t, "a84442009c09b1adc278b6bb80a3853419f54007", response.Properties.OriginalCommit)
|
||||
assert.True(t, ok)
|
||||
assert.NotNil(t, response)
|
||||
assert.Equal(t, 1337, response.PRIndex)
|
||||
assert.Equal(t, "a84442009c09b1adc278b6bb80a3853419f54007", response.Properties.OriginalCommit)
|
||||
assert.True(t, ok)
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewWebhookInvalidJSON(t *testing.T) {
|
||||
raw := []byte(`{ "serverUrl": ["invalid-server-url-content"] }`)
|
||||
_, ok := New(raw)
|
||||
t.Run("Invalid JSON", func(t *testing.T) {
|
||||
raw := []byte(`{ "serverUrl": ["invalid-server-url-content"] }`)
|
||||
_, ok := New(raw)
|
||||
|
||||
assert.False(t, ok)
|
||||
}
|
||||
assert.False(t, ok)
|
||||
})
|
||||
|
||||
func TestNewWebhookInvalidBranchName(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
t.Run("Invalid branch name", func(t *testing.T) {
|
||||
settings.Pattern = &settings.PatternConfig{
|
||||
RegExp: regexp.MustCompile(`^PR-(\d+)$`),
|
||||
}
|
||||
|
||||
raw := []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "invalid", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`)
|
||||
_, ok := New(raw)
|
||||
raw := []byte(`{ "serverUrl": "https://example.com/sonarqube", "taskId": "AXouyxDpizdp4B1K", "status": "SUCCESS", "analysedAt": "2021-05-21T12:12:07+0000", "revision": "f84442009c09b1adc278b6aa80a3853419f54007", "changedAt": "2021-05-21T12:12:07+0000", "project": { "key": "pr-bot", "name": "PR Bot", "url": "https://example.com/sonarqube/dashboard?id=pr-bot" }, "branch": { "name": "invalid", "type": "PULL_REQUEST", "isMain": false, "url": "https://example.com/sonarqube/dashboard?id=pr-bot&pullRequest=PR-1337" }, "qualityGate": { "name": "PR Bot", "status": "OK", "conditions": [ { "metric": "new_reliability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_maintainability_rating", "operator": "GREATER_THAN", "value": "1", "status": "OK", "errorThreshold": "1" }, { "metric": "new_security_hotspots_reviewed", "operator": "LESS_THAN", "status": "NO_VALUE", "errorThreshold": "100" } ] }, "properties": {} }`)
|
||||
_, ok := New(raw)
|
||||
|
||||
assert.False(t, ok)
|
||||
assert.False(t, ok)
|
||||
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
t.Cleanup(func() {
|
||||
settings.Pattern = nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestWebhookGetRevision(t *testing.T) {
|
||||
t.Run("Default revision", func(t *testing.T) {
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
w := Webhook{
|
||||
Revision: "225fa0306c0ab83297d0cb5db0717b194ccb2e76",
|
||||
}
|
||||
|
@ -58,7 +60,7 @@ func TestWebhookGetRevision(t *testing.T) {
|
|||
assert.Equal(t, w.Revision, w.GetRevision())
|
||||
})
|
||||
|
||||
t.Run("Default revision due to incomplete properties", func(t *testing.T) {
|
||||
t.Run("Incomplete properties", func(t *testing.T) {
|
||||
w := Webhook{
|
||||
Revision: "225fa0306c0ab83297d0cb5db0717b194ccb2e76",
|
||||
Properties: &properties{},
|
||||
|
|
Loading…
Reference in a new issue