diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2018-02-14 15:54:21 +0100 |
---|---|---|
committer | Guillaume Jambet <guillaume.jambet@gmail.com> | 2018-03-01 15:21:05 +0100 |
commit | bad30545b5ed235f7778c00baedbbe0e41006049 (patch) | |
tree | f6b9e864dcbe2d0c0d2eca070a73a01d734caeef /tests | |
parent | 5caae9b3367cdad3c31d2ed8a7031efd8dfe71c3 (diff) | |
download | sonarqube-bad30545b5ed235f7778c00baedbbe0e41006049.tar.gz sonarqube-bad30545b5ed235f7778c00baedbbe0e41006049.zip |
SONAR-10345 Add IT's for webhooks management
Diffstat (limited to 'tests')
5 files changed, 206 insertions, 224 deletions
diff --git a/tests/src/test/java/org/sonarqube/tests/project/ProjectBadgesTest.java b/tests/src/test/java/org/sonarqube/tests/project/ProjectBadgesTest.java index 161861e58b1..3e9f23f0a60 100644 --- a/tests/src/test/java/org/sonarqube/tests/project/ProjectBadgesTest.java +++ b/tests/src/test/java/org/sonarqube/tests/project/ProjectBadgesTest.java @@ -115,7 +115,7 @@ public class ProjectBadgesTest { } private void shouldHaveUrl(SelenideElement badgesModal, String url) { - badgesModal.$(".badge-snippet pre") + badgesModal.$(".code-snippet pre") .shouldBe(Condition.visible) .shouldHave(Condition.text(url)); } diff --git a/tests/src/test/java/org/sonarqube/tests/webhook/ExternalServer.java b/tests/src/test/java/org/sonarqube/tests/webhook/ExternalServer.java index 220dc1f59e5..66cdb5c2413 100644 --- a/tests/src/test/java/org/sonarqube/tests/webhook/ExternalServer.java +++ b/tests/src/test/java/org/sonarqube/tests/webhook/ExternalServer.java @@ -93,7 +93,18 @@ class ExternalServer extends ExternalResource { return jetty.getURI().resolve(path).toString(); } + void waitUntilAllWebHooksCalled(int expectedNumberOfRequests) throws InterruptedException { + // Wait up to 30 seconds max + for (int i = 0; i < 60; i++) { + if (getPayloadRequests().size() == expectedNumberOfRequests) { + break; + } + Thread.sleep(500); + } + } + void clear() { payloads.clear(); } + } diff --git a/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksPageTest.java b/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksPageTest.java new file mode 100644 index 00000000000..ac3e8ed3318 --- /dev/null +++ b/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksPageTest.java @@ -0,0 +1,139 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.tests.webhook; + +import com.sonar.orchestrator.Orchestrator; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonarqube.qa.util.Tester; +import org.sonarqube.qa.util.pageobjects.WebhooksPage; +import org.sonarqube.ws.Projects.CreateWsResponse.Project; +import org.sonarqube.ws.Users.CreateWsResponse.User; +import org.sonarqube.ws.Webhooks.CreateWsResponse.Webhook; + +import static util.ItUtils.runProjectAnalysis; + +public class WebhooksPageTest +{ + @ClassRule + public static Orchestrator orchestrator = WebhooksSuite.ORCHESTRATOR; + + @Rule + public Tester tester = new Tester(orchestrator); + + @Before + @After + public void reset() { + tester.webhooks().deleteAllGlobal(); + } + + @Test + public void list_global_webhooks() { + tester.webhooks().generate(); + Webhook webhook = tester.webhooks().generate(); + tester.wsClient().users().skipOnboardingTutorial(); + WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials("admin").openWebhooks(); + webhooksPage + .countWebhooks(2) + .hasWebhook(webhook.getUrl()) + .hasWebhook(webhook.getName()); + } + + @Test + public void list_project_webhooks() { + User user = tester.users().generateAdministratorOnDefaultOrganization(); + tester.wsClient().users().skipOnboardingTutorial(); + + Project project = tester.projects().provision(); + analyseProject(project); + + Webhook webhook1 = tester.webhooks().generate(project); + Webhook webhook2 = tester.webhooks().generate(project); + + WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials(user.getLogin()).openProjectWebhooks(project.getKey()); + webhooksPage + .countWebhooks(2) + .hasWebhook(webhook1.getUrl()) + .hasWebhook(webhook2.getUrl()); + } + + @Test + public void create_new_webhook() { + User user = tester.users().generateAdministratorOnDefaultOrganization(); + tester.wsClient().users().skipOnboardingTutorial(); + + Project project = tester.projects().provision(); + analyseProject(project); + + WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials(user.getLogin()).openProjectWebhooks(project.getKey()); + webhooksPage + .hasNoWebhooks() + .createWebhook("my-webhook", "http://greg:pass@test.com") + .countWebhooks(1) + .hasWebhook("my-webhook") + .hasWebhook("http://greg:pass@test.com"); + } + + @Test + public void prevent_webhook_creation() { + tester.wsClient().users().skipOnboardingTutorial(); + + Webhook webhook = tester.webhooks().generate(); + for (int i = 0; i < 9; i++) { + tester.webhooks().generate(); + } + + WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials("admin").openWebhooks(); + webhooksPage + .countWebhooks(10) + .createIsDisabled() + .deleteWebhook(webhook.getName()) + .countWebhooks(9) + .createWebhook("my-new-webhook", "http://my-new-webhook.com"); + } + + @Test + public void delete_webhook() { + User user = tester.users().generateAdministratorOnDefaultOrganization(); + tester.wsClient().users().skipOnboardingTutorial(); + + Project project = tester.projects().provision(); + analyseProject(project); + + tester.webhooks().generate(project); + tester.webhooks().generate(project); + Webhook webhook = tester.webhooks().generate(project); + + WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials(user.getLogin()).openProjectWebhooks(project.getKey()); + webhooksPage + .countWebhooks(3) + .deleteWebhook(webhook.getName()) + .countWebhooks(2); + } + + private void analyseProject(Project project) { + runProjectAnalysis(orchestrator, "shared/xoo-sample", + "sonar.projectKey", project.getKey(), + "sonar.projectName", project.getName()); + } +} diff --git a/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksSuite.java b/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksSuite.java index 261c88ff139..6412ec5c48e 100644 --- a/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksSuite.java +++ b/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksSuite.java @@ -28,6 +28,7 @@ import static util.ItUtils.xooPlugin; @RunWith(Suite.class) @Suite.SuiteClasses({ + WebhooksPageTest.class, WebhooksTest.class }) public class WebhooksSuite { diff --git a/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksTest.java b/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksTest.java index 2531d8674b1..ad73ced0d2b 100644 --- a/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksTest.java +++ b/tests/src/test/java/org/sonarqube/tests/webhook/WebhooksTest.java @@ -20,64 +20,41 @@ package org.sonarqube.tests.webhook; import com.sonar.orchestrator.Orchestrator; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; -import javax.annotation.Nullable; -import org.apache.commons.lang3.StringUtils; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.sonarqube.qa.util.Tester; -import org.sonarqube.qa.util.pageobjects.WebhooksPage; import org.sonarqube.ws.Issues.Issue; import org.sonarqube.ws.Organizations.Organization; import org.sonarqube.ws.Projects.CreateWsResponse.Project; import org.sonarqube.ws.Qualitygates; import org.sonarqube.ws.Qualityprofiles.CreateWsResponse.QualityProfile; -import org.sonarqube.ws.Users; -import org.sonarqube.ws.Users.CreateWsResponse.User; import org.sonarqube.ws.Webhooks; -import org.sonarqube.ws.client.HttpException; -import org.sonarqube.ws.client.WsClient; +import org.sonarqube.ws.Webhooks.CreateWsResponse.Webhook; import org.sonarqube.ws.client.issues.BulkChangeRequest; import org.sonarqube.ws.client.issues.SearchRequest; -import org.sonarqube.ws.client.projects.DeleteRequest; import org.sonarqube.ws.client.qualitygates.CreateConditionRequest; -import org.sonarqube.ws.client.settings.ResetRequest; -import org.sonarqube.ws.client.settings.SetRequest; -import org.sonarqube.ws.client.webhooks.DeliveriesRequest; -import org.sonarqube.ws.client.webhooks.DeliveryRequest; -import util.ItUtils; import static java.util.Collections.singletonList; -import static java.util.Objects.requireNonNull; -import static java.util.stream.IntStream.range; import static org.assertj.core.api.Assertions.assertThat; import static util.ItUtils.jsonToMap; import static util.ItUtils.runProjectAnalysis; public class WebhooksTest { - private static final String PROJECT_KEY = "my-project"; - private static final String PROJECT_NAME = "My Project"; - private static final String GLOBAL_WEBHOOK_PROPERTY = "sonar.webhooks.global"; - private static final String PROJECT_WEBHOOK_PROPERTY = "sonar.webhooks.project"; - @ClassRule public static Orchestrator orchestrator = WebhooksSuite.ORCHESTRATOR; + @ClassRule public static ExternalServer externalServer = new ExternalServer(); @Rule public Tester tester = new Tester(orchestrator); - private WsClient adminWs = ItUtils.newAdminWsClient(orchestrator); - @Before public void setUp() { externalServer.clear(); @@ -86,28 +63,20 @@ public class WebhooksTest { @Before @After public void reset() { - disableGlobalWebhooks(); - try { - // delete project and related properties/webhook deliveries - adminWs.projects().delete(new DeleteRequest().setProject(PROJECT_KEY)); - } catch (HttpException e) { - // ignore because project may not exist - } + tester.webhooks().deleteAllGlobal(); } @Test public void call_multiple_global_and_project_webhooks_when_analysis_is_done() throws InterruptedException { - orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_NAME); - enableGlobalWebhooks( - new Webhook("Jenkins", externalServer.urlFor("/jenkins")), - new Webhook("HipChat", externalServer.urlFor("/hipchat"))); - enableProjectWebhooks(PROJECT_KEY, - new Webhook("Burgr", externalServer.urlFor("/burgr"))); + Project project = tester.projects().provision(); + Webhook jenkins = tester.webhooks().generate(p -> p.setName("Jenkins").setUrl(externalServer.urlFor("/jenkins"))); + Webhook hipchat = tester.webhooks().generate(p -> p.setName("HipChat").setUrl(externalServer.urlFor("/hipchat"))); + Webhook burgr = tester.webhooks().generate(project, p -> p.setName("Burgr").setUrl(externalServer.urlFor("/burgr"))); - analyseProject(); + analyseProject(project); // the same payload has been sent to three servers - waitUntilAllWebHooksCalled(3); + externalServer.waitUntilAllWebHooksCalled(3); assertThat(externalServer.getPayloadRequests()).hasSize(3); PayloadRequest request = externalServer.getPayloadRequests().get(0); for (int i = 1; i < 3; i++) { @@ -116,137 +85,104 @@ public class WebhooksTest { } // verify HTTP headers - assertThat(request.getHttpHeaders().get("X-SonarQube-Project")).isEqualTo(PROJECT_KEY); + assertThat(request.getHttpHeaders().get("X-SonarQube-Project")).isEqualTo(project.getKey()); // verify content of payload Map<String, Object> payload = jsonToMap(request.getJson()); assertThat(payload.get("status")).isEqualTo("SUCCESS"); assertThat(payload.get("analysedAt")).isNotNull(); - Map<String, String> project = (Map<String, String>) payload.get("project"); - assertThat(project.get("key")).isEqualTo(PROJECT_KEY); - assertThat(project.get("name")).isEqualTo(PROJECT_NAME); - assertThat(project.get("url")).isEqualTo(orchestrator.getServer().getUrl() + "/dashboard?id=" + PROJECT_KEY); + Map<String, String> projectPayload = (Map<String, String>) payload.get("project"); + assertThat(projectPayload.get("key")).isEqualTo(project.getKey()); + assertThat(projectPayload.get("name")).isEqualTo(project.getName()); + assertThat(projectPayload.get("url")).isEqualTo(orchestrator.getServer().getUrl() + "/dashboard?id=" + project.getKey()); Map<String, Object> gate = (Map<String, Object>) payload.get("qualityGate"); assertThat(gate.get("name")).isEqualTo("Sonar way"); assertThat(gate.get("status")).isEqualTo("OK"); assertThat(gate.get("conditions")).isNotNull(); // verify list of persisted deliveries (api/webhooks/deliveries) - List<Webhooks.Delivery> deliveries = getPersistedDeliveries(); + List<Webhooks.Delivery> deliveries = tester.webhooks().getPersistedDeliveries(project); assertThat(deliveries).hasSize(3); for (Webhooks.Delivery delivery : deliveries) { - assertThatPersistedDeliveryIsValid(delivery); + tester.webhooks().assertThatPersistedDeliveryIsValid(delivery, project, externalServer.urlFor("/")); assertThat(delivery.getSuccess()).isTrue(); assertThat(delivery.getHttpStatus()).isEqualTo(200); - assertThat(delivery.getName()).isIn("Jenkins", "HipChat", "Burgr"); + assertThat(delivery.getName()).isIn(jenkins.getName(), hipchat.getName(), burgr.getName()); assertThat(delivery.hasErrorStacktrace()).isFalse(); // payload is available only in api/webhooks/delivery to avoid loading multiple DB CLOBs assertThat(delivery.hasPayload()).isFalse(); } // verify detail of persisted delivery (api/webhooks/delivery) - Webhooks.Delivery detail = getDetailOfPersistedDelivery(deliveries.get(0)); - assertThatPersistedDeliveryIsValid(detail); + Webhooks.Delivery detail = tester.webhooks().getDetailOfPersistedDelivery(deliveries.get(0)); + tester.webhooks().assertThatPersistedDeliveryIsValid(detail, project, externalServer.urlFor("/")); assertThat(detail.getPayload()).isEqualTo(request.getJson()); } @Test public void persist_delivery_as_failed_if_external_server_returns_an_error_code() { - enableGlobalWebhooks( - new Webhook("Fail", externalServer.urlFor("/fail")), - new Webhook("HipChat", externalServer.urlFor("/hipchat"))); + Project project = tester.projects().provision(); + Webhook fail = tester.webhooks().generate(p -> p.setName("Fail").setUrl(externalServer.urlFor("/fail"))); + Webhook hipchat = tester.webhooks().generate(p -> p.setName("HipChat").setUrl(externalServer.urlFor("/hipchat"))); - analyseProject(); + analyseProject(project); // all webhooks are called, even if one returns an error code assertThat(externalServer.getPayloadRequests()).hasSize(2); // verify persisted deliveries - Webhooks.Delivery failedDelivery = getPersistedDeliveryByName("Fail"); - assertThatPersistedDeliveryIsValid(failedDelivery); + Webhooks.Delivery failedDelivery = tester.webhooks().getPersistedDeliveryByName(project, fail.getName()); + tester.webhooks().assertThatPersistedDeliveryIsValid(failedDelivery, project, fail.getUrl()); assertThat(failedDelivery.getSuccess()).isFalse(); assertThat(failedDelivery.getHttpStatus()).isEqualTo(500); - Webhooks.Delivery successfulDelivery = getPersistedDeliveryByName("HipChat"); - assertThatPersistedDeliveryIsValid(successfulDelivery); + Webhooks.Delivery successfulDelivery = tester.webhooks().getPersistedDeliveryByName(project, hipchat.getName()); + tester.webhooks().assertThatPersistedDeliveryIsValid(successfulDelivery, project, hipchat.getUrl()); assertThat(successfulDelivery.getSuccess()).isTrue(); assertThat(successfulDelivery.getHttpStatus()).isEqualTo(200); } - /** - * Restrict calls to ten webhooks per type (global or project) - */ - @Test - public void do_not_become_a_denial_of_service_attacker() throws InterruptedException { - orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_NAME); - - List<Webhook> globalWebhooks = range(0, 15).mapToObj(i -> new Webhook("G" + i, externalServer.urlFor("/global"))).collect(Collectors.toList()); - enableGlobalWebhooks(globalWebhooks.toArray(new Webhook[globalWebhooks.size()])); - List<Webhook> projectWebhooks = range(0, 15).mapToObj(i -> new Webhook("P" + i, externalServer.urlFor("/project"))).collect(Collectors.toList()); - enableProjectWebhooks(PROJECT_KEY, projectWebhooks.toArray(new Webhook[projectWebhooks.size()])); - - analyseProject(); - - // only the first ten global webhooks and ten project webhooks are called - waitUntilAllWebHooksCalled(10 + 10); - assertThat(externalServer.getPayloadRequests()).hasSize(10 + 10); - assertThat(externalServer.getPayloadRequestsOnPath("/global")).hasSize(10); - assertThat(externalServer.getPayloadRequestsOnPath("/project")).hasSize(10); - - // verify persisted deliveries - assertThat(getPersistedDeliveries()).hasSize(10 + 10); - } - @Test - public void persist_delivery_as_failed_if_webhook_url_is_malformed() { - enableGlobalWebhooks(new Webhook("Jenkins", "this_is_not_an_url")); + public void persist_delivery_as_failed_if_webhook_is_not_reachable() { + Project project = tester.projects().provision(); + Webhook badUrl = tester.webhooks().generate(p -> p.setUrl("http://does_not_exist")); - analyseProject(); + analyseProject(project); assertThat(externalServer.getPayloadRequests()).isEmpty(); // verify persisted deliveries - Webhooks.Delivery delivery = getPersistedDeliveryByName("Jenkins"); - Webhooks.Delivery detail = getDetailOfPersistedDelivery(delivery); + Webhooks.Delivery delivery = tester.webhooks().getPersistedDeliveryByName(project, badUrl.getName()); + Webhooks.Delivery detail = tester.webhooks().getDetailOfPersistedDelivery(delivery); assertThat(detail.getSuccess()).isFalse(); assertThat(detail.hasHttpStatus()).isFalse(); assertThat(detail.hasDurationMs()).isFalse(); assertThat(detail.getPayload()).isNotEmpty(); assertThat(detail.getErrorStacktrace()) - .contains("java.lang.IllegalArgumentException") - .contains("Webhook URL is not valid: this_is_not_an_url"); - } - - @Test - public void ignore_webhook_if_url_is_missing() { - // property sets, as used to define webhooks, do - // not allow to validate values yet - enableGlobalWebhooks(new Webhook("Jenkins", null)); - - analyseProject(); - - assertThat(externalServer.getPayloadRequests()).isEmpty(); - assertThat(getPersistedDeliveries()).isEmpty(); + .contains("java.net.UnknownHostException") + .contains("Name or service not known"); } @Test public void send_webhook_on_issue_change() throws InterruptedException { Organization defaultOrganization = tester.organizations().getDefaultOrganization(); - Project wsProject = tester.projects().provision(r -> r.setProject(PROJECT_KEY).setName(PROJECT_NAME)); - enableProjectWebhooks(PROJECT_KEY, new Webhook("Burgr", externalServer.urlFor("/burgr"))); + Project project = tester.projects().provision(); + Webhook burgr = tester.webhooks().generate(project, p -> p.setName("Burgr").setUrl(externalServer.urlFor("/burgr"))); + // quality profile with one issue per line QualityProfile qualityProfile = tester.qProfiles().createXooProfile(defaultOrganization); tester.qProfiles().activateRule(qualityProfile, "xoo:OneIssuePerLine"); - tester.qProfiles().assignQProfileToProject(qualityProfile, wsProject); + tester.qProfiles().assignQProfileToProject(qualityProfile, project); // quality gate definition Qualitygates.CreateResponse qGate = tester.qGates().generate(); tester.qGates().service().createCondition(new CreateConditionRequest().setGateId(String.valueOf(qGate.getId())) .setMetric("reliability_rating").setOp("GT").setError("1")); - tester.qGates().associateProject(qGate, wsProject); + tester.qGates().associateProject(qGate, project); // analyze project and clear first webhook - analyseProject(); - waitUntilAllWebHooksCalled(1); + + analyseProject(project); + externalServer.waitUntilAllWebHooksCalled(1); externalServer.clear(); // change an issue to blocker bug, QG status goes from OK to ERROR, so webhook is called @@ -255,18 +191,18 @@ public class WebhooksTest { tester.wsClient().issues().bulkChange(new BulkChangeRequest().setIssues(singletonList(firstIssue.getKey())) .setSetSeverity(singletonList("BLOCKER")) .setSetType(singletonList("BUG"))); - waitUntilAllWebHooksCalled(1); + externalServer.waitUntilAllWebHooksCalled(1); PayloadRequest request = externalServer.getPayloadRequests().get(0); - assertThat(request.getHttpHeaders().get("X-SonarQube-Project")).isEqualTo(PROJECT_KEY); + assertThat(request.getHttpHeaders().get("X-SonarQube-Project")).isEqualTo(project.getKey()); // verify content of payload Map<String, Object> payload = jsonToMap(request.getJson()); assertThat(payload.get("status")).isEqualTo("SUCCESS"); assertThat(payload.get("analysedAt")).isNotNull(); - Map<String, String> project = (Map<String, String>) payload.get("project"); - assertThat(project.get("key")).isEqualTo(PROJECT_KEY); - assertThat(project.get("name")).isEqualTo(PROJECT_NAME); - assertThat(project.get("url")).isEqualTo(orchestrator.getServer().getUrl() + "/dashboard?id=" + PROJECT_KEY); + Map<String, String> projectPayload = (Map<String, String>) payload.get("project"); + assertThat(projectPayload.get("key")).isEqualTo(project.getKey()); + assertThat(projectPayload.get("name")).isEqualTo(project.getName()); + assertThat(projectPayload.get("url")).isEqualTo(orchestrator.getServer().getUrl() + "/dashboard?id=" + project.getKey()); Map<String, Object> gate = (Map<String, Object>) payload.get("qualityGate"); assertThat(gate.get("name")).isEqualTo(qGate.getName()); assertThat(gate.get("status")).isEqualTo("ERROR"); @@ -276,127 +212,22 @@ public class WebhooksTest { // change severity of issue, won't change the QG status, so no webhook called tester.wsClient().issues().bulkChange(new BulkChangeRequest().setIssues(singletonList(firstIssue.getKey())) .setSetSeverity(singletonList("MINOR"))); - waitUntilAllWebHooksCalled(1); + externalServer.waitUntilAllWebHooksCalled(1); assertThat(externalServer.getPayloadRequests()).isEmpty(); // resolve issue as won't fix, QG status goes to OK, so webhook called tester.wsClient().issues().bulkChange(new BulkChangeRequest().setIssues(singletonList(firstIssue.getKey())) .setDoTransition("wontfix")); - waitUntilAllWebHooksCalled(1); + externalServer.waitUntilAllWebHooksCalled(1); request = externalServer.getPayloadRequests().get(0); payload = jsonToMap(request.getJson()); gate = (Map<String, Object>) payload.get("qualityGate"); assertThat(gate.get("status")).isEqualTo("OK"); } - @Test - public void list_global_webhooks() { - enableGlobalWebhooks(new Webhook("foo", "http://foo.bar"), new Webhook("bar", "https://bar.baz/test")); - tester.wsClient().users().skipOnboardingTutorial(); - WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials("admin").openWebhooks(); - webhooksPage - .countWebhooks(2) - .hasWebhook("http://foo.bar"); - } - - @Test - public void list_project_webhooks() { - analyseProject(); - enableProjectWebhooks(PROJECT_KEY, new Webhook("foo", "http://foo.bar"), new Webhook("bar", "https://bar.baz/test")); - User user = tester.users().generateAdministratorOnDefaultOrganization(); - tester.wsClient().users().skipOnboardingTutorial(); - WebhooksPage webhooksPage = tester.openBrowser().logIn().submitCredentials(user.getLogin()).openProjectWebhooks(PROJECT_KEY); - webhooksPage - .countWebhooks(2) - .hasWebhook("http://foo.bar"); - } - - private void analyseProject() { + private void analyseProject(Project project) { runProjectAnalysis(orchestrator, "shared/xoo-sample", - "sonar.projectKey", PROJECT_KEY, - "sonar.projectName", PROJECT_NAME); - } - - private List<Webhooks.Delivery> getPersistedDeliveries() { - DeliveriesRequest deliveriesReq = new DeliveriesRequest().setComponentKey(PROJECT_KEY); - return adminWs.webhooks().deliveries(deliveriesReq).getDeliveriesList(); - } - - private Webhooks.Delivery getPersistedDeliveryByName(String webhookName) { - List<Webhooks.Delivery> deliveries = getPersistedDeliveries(); - return deliveries.stream().filter(d -> d.getName().equals(webhookName)).findFirst().get(); - } - - private Webhooks.Delivery getDetailOfPersistedDelivery(Webhooks.Delivery delivery) { - Webhooks.Delivery detail = adminWs.webhooks().delivery(new DeliveryRequest().setDeliveryId(delivery.getId())).getDelivery(); - return requireNonNull(detail); - } - - private void assertThatPersistedDeliveryIsValid(Webhooks.Delivery delivery) { - assertThat(delivery.getId()).isNotEmpty(); - assertThat(delivery.getName()).isNotEmpty(); - assertThat(delivery.hasSuccess()).isTrue(); - assertThat(delivery.getHttpStatus()).isGreaterThanOrEqualTo(200); - assertThat(delivery.getDurationMs()).isGreaterThanOrEqualTo(0); - assertThat(delivery.getAt()).isNotEmpty(); - assertThat(delivery.getComponentKey()).isEqualTo(PROJECT_KEY); - assertThat(delivery.getUrl()).startsWith(externalServer.urlFor("/")); - } - - private void enableGlobalWebhooks(Webhook... webhooks) { - enableWebhooks(null, GLOBAL_WEBHOOK_PROPERTY, webhooks); - } - - private void enableProjectWebhooks(String projectKey, Webhook... webhooks) { - enableWebhooks(projectKey, PROJECT_WEBHOOK_PROPERTY, webhooks); - } - - private void enableWebhooks(@Nullable String projectKey, String property, Webhook... webhooks) { - List<String> webhookIds = new ArrayList<>(); - for (int i = 0; i < webhooks.length; i++) { - Webhook webhook = webhooks[i]; - String id = String.valueOf(i + 1); - webhookIds.add(id); - setProperty(projectKey, property + "." + id + ".name", webhook.name); - setProperty(projectKey, property + "." + id + ".url", webhook.url); - } - setProperty(projectKey, property, StringUtils.join(webhookIds, ",")); + "sonar.projectKey", project.getKey(), + "sonar.projectName", project.getName()); } - - private void disableGlobalWebhooks() { - setProperty(null, GLOBAL_WEBHOOK_PROPERTY, null); - } - - private void setProperty(@Nullable String componentKey, String key, @Nullable String value) { - if (value == null) { - ResetRequest req = new ResetRequest().setKeys(Collections.singletonList(key)).setComponent(componentKey); - adminWs.settings().reset(req); - } else { - SetRequest req = new SetRequest().setKey(key).setValue(value).setComponent(componentKey); - adminWs.settings().set(req); - } - } - - private static class Webhook { - private final String name; - private final String url; - - Webhook(@Nullable String name, @Nullable String url) { - this.name = name; - this.url = url; - } - } - - /** - * Wait up to 30 seconds - */ - private static void waitUntilAllWebHooksCalled(int expectedNumberOfRequests) throws InterruptedException { - for (int i = 0; i < 60; i++) { - if (externalServer.getPayloadRequests().size() == expectedNumberOfRequests) { - break; - } - Thread.sleep(500); - } - } - } |