3 * Copyright (C) 2009-2022 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.webhook.ws;
22 import org.junit.Before;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.sonar.api.server.ws.WebService;
26 import org.sonar.api.utils.System2;
27 import org.sonar.api.web.UserRole;
28 import org.sonar.db.DbClient;
29 import org.sonar.db.DbTester;
30 import org.sonar.db.component.ComponentDto;
31 import org.sonar.db.webhook.WebhookDeliveryDto;
32 import org.sonar.server.component.ComponentFinder;
33 import org.sonar.server.component.TestComponentFinder;
34 import org.sonar.server.exceptions.ForbiddenException;
35 import org.sonar.server.exceptions.NotFoundException;
36 import org.sonar.server.exceptions.UnauthorizedException;
37 import org.sonar.server.tester.UserSessionRule;
38 import org.sonar.server.ws.WsActionTester;
39 import org.sonarqube.ws.MediaTypes;
40 import org.sonarqube.ws.Webhooks;
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.assertj.core.api.Assertions.assertThatThrownBy;
44 import static org.sonar.db.webhook.WebhookDeliveryTesting.newDto;
45 import static org.sonar.test.JsonAssert.assertJson;
47 public class WebhookDeliveryActionTest {
50 public UserSessionRule userSession = UserSessionRule.standalone();
53 public DbTester db = DbTester.create(System2.INSTANCE);
55 private DbClient dbClient = db.getDbClient();
56 private WsActionTester ws;
57 private ComponentDto project;
61 ComponentFinder componentFinder = TestComponentFinder.from(db);
62 WebhookDeliveryAction underTest = new WebhookDeliveryAction(dbClient, userSession, componentFinder);
63 ws = new WsActionTester(underTest);
64 project = db.components().insertPrivateProject(c -> c.setDbKey("my-project"));
68 public void test_definition() {
69 WebService.Action definition = ws.getDef();
70 assertThat(definition.isPost()).isFalse();
71 assertThat(definition.isInternal()).isFalse();
72 assertThat(definition.responseExampleAsString()).isNotEmpty();
74 assertThat(definition.params()).hasSize(1);
75 assertThat(definition.param("deliveryId").isRequired()).isTrue();
79 public void throw_UnauthorizedException_if_anonymous() {
80 assertThatThrownBy(() -> ws.newRequest().execute())
81 .isInstanceOf(UnauthorizedException.class);
85 public void return_404_if_delivery_does_not_exist() {
88 assertThatThrownBy(() -> ws.newRequest()
89 .setMediaType(MediaTypes.PROTOBUF)
90 .setParam("deliveryId", "does_not_exist")
92 .isInstanceOf(NotFoundException.class);
96 public void load_the_delivery_of_example() {
97 WebhookDeliveryDto dto = newDto()
99 .setComponentUuid(project.uuid())
100 .setCeTaskUuid("task-1")
102 .setUrl("http://jenkins")
103 .setCreatedAt(1_500_000_000_000L)
107 .setPayload("{\"status\"=\"SUCCESS\"}");
108 dbClient.webhookDeliveryDao().insert(db.getSession(), dto);
110 userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
112 String json = ws.newRequest()
113 .setParam("deliveryId", dto.getUuid())
117 assertJson(json).isSimilarTo(ws.getDef().responseExampleAsString());
121 public void return_delivery_that_failed_to_be_sent() {
122 WebhookDeliveryDto dto = newDto()
123 .setComponentUuid(project.uuid())
126 .setErrorStacktrace("IOException -> can not connect");
127 dbClient.webhookDeliveryDao().insert(db.getSession(), dto);
129 userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
131 Webhooks.DeliveryWsResponse response = ws.newRequest()
132 .setParam("deliveryId", dto.getUuid())
133 .executeProtobuf(Webhooks.DeliveryWsResponse.class);
135 Webhooks.Delivery actual = response.getDelivery();
136 assertThat(actual.hasHttpStatus()).isFalse();
137 assertThat(actual.getErrorStacktrace()).isEqualTo(dto.getErrorStacktrace());
141 public void return_delivery_with_none_of_optional_fields() {
142 WebhookDeliveryDto dto = newDto()
143 .setComponentUuid(project.uuid())
146 .setErrorStacktrace(null)
147 .setAnalysisUuid(null);
148 dbClient.webhookDeliveryDao().insert(db.getSession(), dto);
150 userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
152 Webhooks.DeliveryWsResponse response = ws.newRequest()
153 .setParam("deliveryId", dto.getUuid())
154 .executeProtobuf(Webhooks.DeliveryWsResponse.class);
156 Webhooks.Delivery actual = response.getDelivery();
157 assertThat(actual.hasHttpStatus()).isFalse();
158 assertThat(actual.hasErrorStacktrace()).isFalse();
159 assertThat(actual.hasCeTaskId()).isFalse();
163 public void throw_ForbiddenException_if_not_admin_of_project() {
164 WebhookDeliveryDto dto = newDto()
165 .setComponentUuid(project.uuid());
166 dbClient.webhookDeliveryDao().insert(db.getSession(), dto);
168 userSession.logIn().addProjectPermission(UserRole.USER, project);
170 assertThatThrownBy(() -> ws.newRequest()
171 .setMediaType(MediaTypes.PROTOBUF)
172 .setParam("deliveryId", dto.getUuid())
174 .isInstanceOf(ForbiddenException.class)
175 .hasMessageContaining("Insufficient privileges");