]> source.dussan.org Git - sonarqube.git/blob
053ec2197262dd5dc209ba57a67d5e6ab6f4c59b
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.qualityprofile.ws;
21
22 import java.io.IOException;
23 import java.io.Reader;
24 import java.io.Writer;
25 import javax.annotation.Nullable;
26 import org.apache.commons.io.IOUtils;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.ExpectedException;
30 import org.sonar.api.resources.Languages;
31 import org.sonar.api.server.ws.WebService;
32 import org.sonar.db.DbSession;
33 import org.sonar.db.DbTester;
34 import org.sonar.db.organization.OrganizationDto;
35 import org.sonar.db.qualityprofile.QProfileDto;
36 import org.sonar.server.exceptions.ForbiddenException;
37 import org.sonar.server.exceptions.NotFoundException;
38 import org.sonar.server.exceptions.UnauthorizedException;
39 import org.sonar.server.language.LanguageTesting;
40 import org.sonar.server.organization.DefaultOrganizationProvider;
41 import org.sonar.server.organization.TestDefaultOrganizationProvider;
42 import org.sonar.server.qualityprofile.BulkChangeResult;
43 import org.sonar.server.qualityprofile.QProfileBackuper;
44 import org.sonar.server.qualityprofile.QProfileRestoreSummary;
45 import org.sonar.server.tester.UserSessionRule;
46 import org.sonar.server.ws.TestRequest;
47 import org.sonar.server.ws.TestResponse;
48 import org.sonar.server.ws.WsActionTester;
49 import org.sonar.test.JsonAssert;
50
51 import static org.assertj.core.api.Assertions.assertThat;
52 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
53
54 public class RestoreActionTest {
55
56   private static final String A_LANGUAGE = "xoo";
57
58   @Rule
59   public ExpectedException expectedException = ExpectedException.none();
60   @Rule
61   public DbTester db = DbTester.create();
62   @Rule
63   public UserSessionRule userSession = UserSessionRule.standalone();
64
65   private TestBackuper backuper = new TestBackuper();
66   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
67   private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider);
68   private Languages languages = LanguageTesting.newLanguages(A_LANGUAGE);
69   private WsActionTester tester = new WsActionTester(new RestoreAction(db.getDbClient(), backuper, languages, userSession, wsSupport));
70
71   @Test
72   public void test_definition() {
73     WebService.Action definition = tester.getDef();
74
75     assertThat(definition.key()).isEqualTo("restore");
76     assertThat(definition.isPost()).isTrue();
77     assertThat(definition.responseExampleAsString()).isNull();
78     assertThat(definition.description()).isNotEmpty();
79
80     // parameters
81     assertThat(definition.params()).hasSize(2);
82     WebService.Param backupParam = definition.param("backup");
83     assertThat(backupParam.isRequired()).isTrue();
84     assertThat(backupParam.since()).isNull();
85     WebService.Param orgParam = definition.param("organization");
86     assertThat(orgParam.isRequired()).isFalse();
87     assertThat(orgParam.since()).isEqualTo("6.4");
88   }
89
90   @Test
91   public void profile_is_restored_on_default_organization_with_the_name_provided_in_backup() {
92     logInAsQProfileAdministrator(db.getDefaultOrganization());
93     TestResponse response = restore("<backup/>", null);
94
95     assertThat(backuper.restoredBackup).isEqualTo("<backup/>");
96     assertThat(backuper.restoredSummary.getProfile().getName()).isEqualTo("the-name-in-backup");
97     JsonAssert.assertJson(response.getInput()).isSimilarTo("{" +
98       "  \"profile\": {" +
99       "    \"organization\": \"" + db.getDefaultOrganization().getKey() + "\"," +
100       "    \"name\": \"the-name-in-backup\"," +
101       "    \"language\": \"xoo\"," +
102       "    \"languageName\": \"Xoo\"," +
103       "    \"isDefault\": false," +
104       "    \"isInherited\": false" +
105       "  }," +
106       "  \"ruleSuccesses\": 0," +
107       "  \"ruleFailures\": 0" +
108       "}");
109   }
110
111   @Test
112   public void profile_is_restored_on_specified_organization_with_the_name_provided_in_backup() {
113     OrganizationDto org = db.organizations().insert();
114     logInAsQProfileAdministrator(org);
115     TestResponse response = restore("<backup/>", org.getKey());
116
117     assertThat(backuper.restoredBackup).isEqualTo("<backup/>");
118     assertThat(backuper.restoredSummary.getProfile().getName()).isEqualTo("the-name-in-backup");
119     JsonAssert.assertJson(response.getInput()).isSimilarTo("{" +
120       "  \"profile\": {" +
121       "    \"organization\": \"" + org.getKey() + "\"," +
122       "    \"name\": \"the-name-in-backup\"," +
123       "    \"language\": \"xoo\"," +
124       "    \"languageName\": \"Xoo\"," +
125       "    \"isDefault\": false," +
126       "    \"isInherited\": false" +
127       "  }," +
128       "  \"ruleSuccesses\": 0," +
129       "  \"ruleFailures\": 0" +
130       "}");
131
132   }
133
134   @Test
135   public void throw_IAE_if_backup_is_missing() {
136     logInAsQProfileAdministrator(db.getDefaultOrganization());
137
138     expectedException.expect(IllegalArgumentException.class);
139     expectedException.expectMessage("A backup file must be provided");
140
141     tester.newRequest()
142       .setMethod("POST")
143       .execute();
144   }
145
146   @Test
147   public void throw_ForbiddenException_if_not_profile_administrator_of_default_organization() {
148     userSession.logIn();
149
150     expectedException.expect(ForbiddenException.class);
151     expectedException.expectMessage("Insufficient privileges");
152
153     restore("<backup/>", null);
154   }
155
156   @Test
157   public void throw_ForbiddenException_if_not_profile_administrator_of_specified_organization() {
158     OrganizationDto org = db.organizations().insert();
159     logInAsQProfileAdministrator(db.getDefaultOrganization());
160
161     expectedException.expect(ForbiddenException.class);
162     expectedException.expectMessage("Insufficient privileges");
163
164     restore("<backup/>", org.getKey());
165   }
166
167   @Test
168   public void throw_NotFoundException_if_specified_organization_does_not_exist() {
169     userSession.logIn();
170
171     expectedException.expect(NotFoundException.class);
172     expectedException.expectMessage("No organization with key 'missing'");
173
174     restore("<backup/>", "missing");
175   }
176
177   @Test
178   public void throw_UnauthorizedException_if_not_logged_in() {
179     userSession.anonymous();
180
181     expectedException.expect(UnauthorizedException.class);
182     expectedException.expectMessage("Authentication is required");
183
184     restore("<backup/>", null);
185   }
186
187   private void logInAsQProfileAdministrator(OrganizationDto org) {
188     userSession
189       .logIn()
190       .addPermission(ADMINISTER_QUALITY_PROFILES, org);
191   }
192
193   private TestResponse restore(String backupContent, @Nullable String organizationKey) {
194     TestRequest request = tester.newRequest()
195       .setMethod("POST")
196       .setParam("backup", backupContent);
197     if (organizationKey != null) {
198       request.setParam("organization", organizationKey);
199     }
200     return request.execute();
201   }
202
203   private static class TestBackuper implements QProfileBackuper {
204
205     private String restoredBackup;
206     private QProfileRestoreSummary restoredSummary;
207
208     @Override
209     public void backup(DbSession dbSession, QProfileDto profile, Writer backupWriter) {
210       throw new UnsupportedOperationException();
211     }
212
213     @Override
214     public QProfileRestoreSummary restore(DbSession dbSession, Reader backup, OrganizationDto organization, @Nullable String overriddenProfileName) {
215       if (restoredSummary != null) {
216         throw new IllegalStateException("Already restored");
217       }
218       try {
219         restoredBackup = IOUtils.toString(backup);
220       } catch (IOException e) {
221         throw new IllegalStateException(e);
222       }
223       QProfileDto profile = new QProfileDto()
224         .setKee("P1")
225         .setRulesProfileUuid("rp-P1")
226         .setLanguage("xoo")
227         .setName(overriddenProfileName != null ? overriddenProfileName : "the-name-in-backup");
228       restoredSummary = new QProfileRestoreSummary(profile, new BulkChangeResult());
229       return restoredSummary;
230     }
231
232     @Override
233     public QProfileRestoreSummary restore(DbSession dbSession, Reader backup, QProfileDto profile) {
234       throw new UnsupportedOperationException();
235     }
236   }
237 }