From d66cae2ccaf326eaec5d3cbd1879156c6e591d7b Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 19 Oct 2015 17:56:01 +0200 Subject: [PATCH] Hack for IE - use mime type text/plain for api/qualityprofiles/create --- .../qualityprofile/ws/CreateAction.java | 30 ++++++++--- .../qualityprofile/ws/CreateActionTest.java | 50 ++++++++++++++----- 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java index 07b626edc24..0a40d32a3fd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java @@ -19,6 +19,8 @@ */ package org.sonar.server.qualityprofile.ws; +import java.io.InputStream; +import java.io.OutputStreamWriter; import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.resources.Languages; import org.sonar.api.server.ws.Request; @@ -27,17 +29,16 @@ import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.api.utils.text.JsonWriter; import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QualityProfileDto; -import org.sonar.db.DbClient; +import org.sonar.server.plugins.MimeTypes; import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.qualityprofile.QProfileName; import org.sonar.server.qualityprofile.QProfileResult; import org.sonar.server.user.UserSession; -import java.io.InputStream; - public class CreateAction implements QProfileWsAction { private static final String PARAM_PROFILE_NAME = "name"; @@ -56,7 +57,7 @@ public class CreateAction implements QProfileWsAction { private final UserSession userSession; public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, - Languages languages, ProfileImporter[] importers, UserSession userSession) { + Languages languages, ProfileImporter[] importers, UserSession userSession) { this.dbClient = dbClient; this.profileFactory = profileFactory; this.exporters = exporters; @@ -115,12 +116,29 @@ public class CreateAction implements QProfileWsAction { } } dbSession.commit(); - writeResult(response.newJsonWriter(), result); + + response.stream().setMediaType(guessMediaType(request)); + JsonWriter jsonWriter = JsonWriter.of(new OutputStreamWriter(response.stream().output())); + writeResult(jsonWriter, result); } finally { dbSession.close(); } } + private static String guessMediaType(Request request) { + if (request.getMediaType().contains("html")) { + // this is a hack for IE. + // The form which uploads files (for example PMD or Findbugs configuration files) opens a popup + // to download files if the response type header is application/json. Changing the response type to text/plain, + // even if response body is JSON, fixes the bug. + // This will be fixed in 5.3 when support of IE9/10 will be dropped in order to use + // more recent JS libs. + // We detect that caller is IE because it asks for application/html or text/html + return MimeTypes.TXT; + } + return request.getMediaType(); + } + private void writeResult(JsonWriter json, QProfileResult result) { String language = result.profile().getLanguage(); json.beginObject().name("profile").beginObject() @@ -151,7 +169,7 @@ public class CreateAction implements QProfileWsAction { json.endObject().close(); } - private String getBackupParamName(String importerKey) { + private static String getBackupParamName(String importerKey) { return String.format(PARAM_BACKUP_FORMAT, importerKey); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java index 84636b8ef24..eaa807efb7d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java @@ -21,16 +21,18 @@ package org.sonar.server.qualityprofile.ws; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.server.ws.WebService.Action; import org.sonar.api.utils.System2; import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.QualityProfileDao; import org.sonar.server.db.DbClient; import org.sonar.server.language.LanguageTesting; +import org.sonar.server.plugins.MimeTypes; import org.sonar.server.qualityprofile.QProfileFactory; 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.Mockito.mock; @@ -39,25 +41,47 @@ public class CreateActionTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); + @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); + QualityProfileDao profileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); + DbClient deprecatedDbClient = new DbClient(db.database(), db.myBatis(), profileDao); + @Test public void should_not_fail_on_no_importers() throws Exception { - QualityProfileDao profileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); - DbClient dbClient = new DbClient(db.database(), db.myBatis(), profileDao); + CreateAction underTest = new CreateAction(db.getDbClient(), new QProfileFactory(deprecatedDbClient), null, LanguageTesting.newLanguages("xoo"), userSessionRule); + WsActionTester wsTester = new WsActionTester(underTest); - String xooKey = "xoo"; - WsTester wsTester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), - new CreateAction(dbClient, new QProfileFactory(dbClient), null, LanguageTesting.newLanguages(xooKey), userSessionRule))); + userSessionRule.login("admin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - Action create = wsTester.controller("api/qualityprofiles").action("create"); - assertThat(create.params()).hasSize(2); + TestResponse response = wsTester.newRequest() + .setMethod("POST") + .setMediaType(MimeTypes.JSON) + .setParam("language", "xoo") + .setParam("name", "Yeehaw!") + .execute(); + JsonAssert.assertJson(response.getInput()).isSimilarTo(getClass().getResource("CreateActionTest/create-no-importer.json")); + assertThat(response.getMediaType()).isEqualTo(MimeTypes.JSON); + } + + /** + * Do not return JSON content type header on IE. + */ + @Test + public void test_ie_hack() throws Exception { + CreateAction underTest = new CreateAction(db.getDbClient(), new QProfileFactory(deprecatedDbClient), null, LanguageTesting.newLanguages("xoo"), userSessionRule); + WsActionTester wsTester = new WsActionTester(underTest); + userSessionRule.login("admin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - userSessionRule.login("anakin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + TestResponse response = wsTester.newRequest() + .setMethod("POST") + // IE asks for application/html or text/html + .setMediaType("application/html") + .setParam("language", "xoo") + .setParam("name", "Yeehaw!") + .execute(); + assertThat(response.getMediaType()).isEqualTo(MimeTypes.TXT); - wsTester.newPostRequest("api/qualityprofiles", "create") - .setParam("language", xooKey).setParam("name", "Yeehaw!").execute().assertJson(getClass(), "create-no-importer.json"); } } -- 2.39.5