import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
-import org.apache.commons.io.IOUtils;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.Request;
import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.QProfileBackuper;
-import static com.google.common.base.Preconditions.checkArgument;
-
public class RestoreAction implements QProfileWsAction {
private static final String PARAM_BACKUP = "backup";
private final QProfileBackuper backuper;
private final Languages languages;
- private final QProfileWsSupport qProfileWsSupport;
+ private final QProfileWsSupport wsSupport;
- public RestoreAction(QProfileBackuper backuper, Languages languages, QProfileWsSupport qProfileWsSupport) {
+ public RestoreAction(QProfileBackuper backuper, Languages languages, QProfileWsSupport wsSupport) {
this.backuper = backuper;
this.languages = languages;
- this.qProfileWsSupport = qProfileWsSupport;
+ this.wsSupport = wsSupport;
}
@Override
public void define(WebService.NewController controller) {
- controller.createAction("restore")
+ WebService.NewAction action = controller.createAction("restore")
.setSince("5.2")
.setDescription("Restore a quality profile using an XML file. The restored profile name is taken from the backup file, " +
"so if a profile with the same name and language already exists, it will be overwritten. " +
"Require Administer Quality Profiles permission.")
.setPost(true)
- .setHandler(this)
- .createParam(PARAM_BACKUP)
+ .setHandler(this);
+
+ action.createParam(PARAM_BACKUP)
.setDescription("A profile backup file in XML format, as generated by api/qualityprofiles/backup " +
"or the former api/profiles/backup.")
.setRequired(true);
@Override
public void handle(Request request, Response response) throws Exception {
- qProfileWsSupport.checkQProfileAdminPermission();
-
- InputStream backup = request.paramAsInputStream(PARAM_BACKUP);
- InputStreamReader reader = null;
+ wsSupport.checkQProfileAdminPermission();
- try {
- checkArgument(backup != null, "A backup file must be provided");
- reader = new InputStreamReader(backup, StandardCharsets.UTF_8);
+ try (InputStream backup = request.paramAsInputStream(PARAM_BACKUP);
+ InputStreamReader reader = new InputStreamReader(backup, StandardCharsets.UTF_8)) {
BulkChangeResult result = backuper.restore(reader, null);
writeResponse(response.newJsonWriter(), result);
- } finally {
- IOUtils.closeQuietly(reader);
- IOUtils.closeQuietly(backup);
}
}
new SearchAction(null, languages),
new SetDefaultAction(languages, null, null, wsSupport),
new ProjectsAction(null, userSessionRule),
- new RestoreAction(null, languages, wsSupport),
new ChangelogAction(null, mock(QProfileFactory.class), languages, dbClient),
new ChangeParentAction(dbClient, null, null, languages, wsSupport),
new CompareAction(null, null, languages),
assertThat(projects.responseExampleAsString()).isNotEmpty();
}
- @Test
- public void define_restore_action() {
- WebService.Action restore = controller.action("restore");
- assertThat(restore).isNotNull();
- assertThat(restore.isPost()).isTrue();
- assertThat(restore.params()).hasSize(1);
- }
-
@Test
public void define_bulk_deactivate_rule_action() {
WebService.Action restoreProfiles = controller.action(BulkRuleActivationActions.BULK_DEACTIVATE_ACTION);
package org.sonar.server.qualityprofile.ws;
import java.io.Reader;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.qualityprofile.QProfileBackuper;
import org.sonar.server.qualityprofile.QProfileName;
import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+import org.sonar.test.JsonAssert;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
-@RunWith(MockitoJUnitRunner.class)
public class RestoreActionTest {
+
+ private static final String A_LANGUAGE = "xoo";
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create();
-
@Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ public UserSessionRule userSession = UserSessionRule.standalone();
- // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed
- @Mock
- private QProfileBackuper backuper;
+ private QProfileBackuper backuper = mock(QProfileBackuper.class);
+ private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
+ private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider);
+ private Languages languages = LanguageTesting.newLanguages(A_LANGUAGE);
+ private WsActionTester tester = new WsActionTester(new RestoreAction(backuper, languages, wsSupport));
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
+ @Test
+ public void test_definition() {
+ WebService.Action definition = tester.getDef();
- private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1");
- private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSessionRule, defaultOrganizationProvider);
- private WsTester tester;
+ assertThat(definition.key()).isEqualTo("restore");
+ assertThat(definition.isPost()).isTrue();
+ assertThat(definition.responseExampleAsString()).isNull();
+ assertThat(definition.description()).isNotEmpty();
- @Before
- public void setUp() {
- tester = new WsTester(new QProfilesWs(
- mock(RuleActivationActions.class),
- mock(BulkRuleActivationActions.class),
- new RestoreAction(backuper, LanguageTesting.newLanguages("xoo"), wsSupport)));
+ // parameters
+ assertThat(definition.params()).hasSize(1);
+ assertThat(definition.param("backup").isRequired()).isTrue();
}
@Test
- public void restore_profile() throws Exception {
- logInAsQProfileAdministrator();
-
- QualityProfileDto profile = QualityProfileDto.createFor("xoo-sonar-way-12345")
+ public void restore_the_uploaded_backup_on_default_organization() throws Exception {
+ QualityProfileDto profile = QualityProfileDto.createFor("P1")
.setDefault(false).setLanguage("xoo").setName("Sonar way");
BulkChangeResult restoreResult = new BulkChangeResult(profile);
- when(backuper.restore(any(Reader.class), (QProfileName) eq(null))).thenReturn(restoreResult);
+ when(backuper.restore(any(Reader.class), any(QProfileName.class))).thenReturn(restoreResult);
+
+ logInAsQProfileAdministrator(db.getDefaultOrganization());
+ TestResponse response = restore("<backup/>");
- tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "<polop><palap/></polop>").execute()
- .assertJson(getClass(), "restore_profile.json");
- verify(backuper).restore(any(Reader.class), (QProfileName) eq(null));
+ JsonAssert.assertJson(response.getInput()).isSimilarTo(getClass().getResource("RestoreActionTest/restore_profile.json"));
+ verify(backuper).restore(any(Reader.class), any(QProfileName.class));
}
@Test
- public void fail_on_missing_backup() throws Exception {
- logInAsQProfileAdministrator();
+ public void throw_IAE_if_backup_is_missing() throws Exception {
+ logInAsQProfileAdministrator(db.getDefaultOrganization());
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("A backup file must be provided");
- tester.newPostRequest("api/qualityprofiles", "restore").execute();
+ tester.newRequest()
+ .setMethod("POST")
+ .execute();
}
@Test
public void throw_ForbiddenException_if_not_profile_administrator() throws Exception {
- userSessionRule.logIn();
+ userSession.logIn();
expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");
- tester.newPostRequest("api/qualityprofiles", "restore").execute();
+ restore("<backup/>");
}
@Test
public void throw_UnauthorizedException_if_not_logged_in() throws Exception {
+ userSession.anonymous();
+
expectedException.expect(UnauthorizedException.class);
expectedException.expectMessage("Authentication is required");
- tester.newPostRequest("api/qualityprofiles", "restore").execute();
+ restore("<backup/>");
}
- private void logInAsQProfileAdministrator() {
- userSessionRule
+ private void logInAsQProfileAdministrator(OrganizationDto org) {
+ userSession
.logIn()
- .addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid());
+ .addPermission(ADMINISTER_QUALITY_PROFILES, org);
+ }
+
+ private TestResponse restore(String backupContent) {
+ return tester.newRequest()
+ .setMethod("POST")
+ .setParam("backup", backupContent)
+ .execute();
}
}