Sfoglia il codice sorgente

SONAR-8460 WS errors does not return bundled messages

tags/6.3-RC1
Julien Lancelot 7 anni fa
parent
commit
57561f65d0
32 ha cambiato i file con 316 aggiunte e 519 eliminazioni
  1. 1
    1
      it/it-tests/src/test/java/it/user/SsoAuthenticationTest.java
  2. 3
    11
      server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java
  3. 2
    7
      server/sonar-server/src/main/java/org/sonar/server/exceptions/Errors.java
  4. 12
    41
      server/sonar-server/src/main/java/org/sonar/server/exceptions/Message.java
  5. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/exceptions/Verifications.java
  6. 5
    19
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java
  7. 4
    4
      server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java
  8. 3
    5
      server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java
  9. 3
    4
      server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java
  10. 3
    5
      server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java
  11. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java
  12. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java
  13. 3
    5
      server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java
  14. 4
    4
      server/sonar-server/src/main/java/org/sonar/server/util/Validation.java
  15. 2
    5
      server/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java
  16. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/authentication/SsoAuthenticatorTest.java
  17. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/email/ws/SendActionTest.java
  18. 10
    12
      server/sonar-server/src/test/java/org/sonar/server/exceptions/MessageTest.java
  19. 13
    11
      server/sonar-server/src/test/java/org/sonar/server/exceptions/VerificationsTest.java
  20. 3
    4
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java
  21. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
  22. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
  23. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java
  24. 178
    240
      server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterTest.java
  25. 14
    20
      server/sonar-server/src/test/java/org/sonar/server/util/BooleanTypeValidationTest.java
  26. 9
    15
      server/sonar-server/src/test/java/org/sonar/server/util/FloatTypeValidationTest.java
  27. 13
    23
      server/sonar-server/src/test/java/org/sonar/server/util/IntegerTypeValidationTest.java
  28. 2
    0
      server/sonar-server/src/test/java/org/sonar/server/util/LongTypeValidationTest.java
  29. 9
    16
      server/sonar-server/src/test/java/org/sonar/server/util/StringListTypeValidationTest.java
  30. 4
    2
      server/sonar-server/src/test/java/org/sonar/server/util/TypeValidationsTest.java
  31. 7
    38
      server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java
  32. 0
    18
      sonar-core/src/main/resources/org/sonar/l10n/core.properties

+ 1
- 1
it/it-tests/src/test/java/it/user/SsoAuthenticationTest.java Vedi File

@@ -131,7 +131,7 @@ public class SsoAuthenticationTest {
assertThat(response.request().url().toString()).contains("sessions/unauthorized");

List<String> logsLines = FileUtils.readLines(orchestrator.getServer().getWebLogs(), Charsets.UTF_8);
assertThat(logsLines).doesNotContain("org.sonar.server.exceptions.BadRequestException: user.bad_login");
assertThat(logsLines).doesNotContain("org.sonar.server.exceptions.BadRequestException: Use only letters, numbers, and .-_@ please.");
USER_RULE.verifyUserDoesNotExist(USER_LOGIN);
}


+ 3
- 11
server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java Vedi File

@@ -32,19 +32,11 @@ public class BadRequestException extends ServerException {

private final transient Errors errors;

/**
* @deprecated Bundle key should be replaced by real message as only english is returned on server side errors
*/
@Deprecated
public BadRequestException(String l10nKey, Object... l10nParams) {
public BadRequestException(String format, Object... arguments) {
super(HTTP_BAD_REQUEST);
this.errors = new Errors().add(Message.of(l10nKey, l10nParams));
this.errors = new Errors().add(Message.of(format, arguments));
}

/**
* @deprecated Bundle key should be replaced by real message as only english is returned on server side errors
*/
@Deprecated
public BadRequestException(List<Message> messages) {
super(HTTP_BAD_REQUEST);
this.errors = new Errors().add(messages);
@@ -73,7 +65,7 @@ public class BadRequestException extends ServerException {

@Override
public String getMessage() {
return firstError().getKey();
return firstError().getMessage();
}

@Override

+ 2
- 7
server/sonar-server/src/main/java/org/sonar/server/exceptions/Errors.java Vedi File

@@ -24,12 +24,8 @@ import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.i18n.I18n;
import org.sonar.api.utils.text.JsonWriter;

import static java.util.Locale.ENGLISH;

public class Errors {

private final List<Message> messages = Lists.newArrayList();
@@ -70,13 +66,12 @@ public class Errors {
return expression;
}

public void writeJson(JsonWriter json, I18n i18n) {
public void writeJson(JsonWriter json) {
if (!messages.isEmpty()) {
json.name("errors").beginArray();
for (Message message : messages) {
json.beginObject();
String text = StringUtils.defaultString(i18n.message(ENGLISH, message.getKey(), message.getKey(), message.getParams()), message.getKey());
json.prop("msg", text);
json.prop("msg", message.getMessage());
json.endObject();
}
json.endArray();

+ 12
- 41
server/sonar-server/src/main/java/org/sonar/server/exceptions/Message.java Vedi File

@@ -19,37 +19,22 @@
*/
package org.sonar.server.exceptions;

import com.google.common.base.MoreObjects;
import java.util.Arrays;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import static java.lang.String.format;

/**
* @deprecated Bundle key should be replaced by real message as only english is returned on server side messages
*/
@Deprecated
public class Message {

private final String key;
private final Object[] params;

private Message(String key, @Nullable Object[] params) {
this.key = key;
this.params = params;
}
private final String msg;

public String getKey() {
return key;
private Message(String format, Object... params) {
this.msg = format(format, params);
}

@CheckForNull
public Object[] getParams() {
return params;
public String getMessage() {
return msg;
}

public static Message of(String l10nKey, Object... l10nParams) {
return new Message(StringUtils.defaultString(l10nKey), l10nParams);
public static Message of(String msg, Object... arguments) {
return new Message(msg, arguments);
}

@Override
@@ -61,31 +46,17 @@ public class Message {
return false;
}

Message message = (Message) o;

if (!key.equals(message.key)) {
return false;
}
// Probably incorrect - comparing Object[] arrays with Arrays.equals
if (!Arrays.equals(params, message.params)) {
return false;
}

return true;
Message other = (Message) o;
return this.msg.equals(other.msg);
}

@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result + (params != null ? Arrays.hashCode(params) : 0);
return result;
return msg.hashCode();
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("key", key)
.add("params", params != null ? Arrays.toString(params) : null)
.toString();
return msg;
}
}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/exceptions/Verifications.java Vedi File

@@ -25,9 +25,9 @@ public class Verifications {
// only static stuff
}

public static void check(boolean expression, String l10nKey, Object... l10nParams) {
public static void check(boolean expression, String format, Object... arguments) {
if (!expression) {
throw new BadRequestException(l10nKey, l10nParams);
throw new BadRequestException(format, arguments);
}
}
}

+ 5
- 19
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java Vedi File

@@ -19,11 +19,9 @@
*/
package org.sonar.server.qualityprofile.ws;

import org.sonar.api.i18n.I18n;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
@@ -44,12 +42,10 @@ public class BulkRuleActivationActions {

private final QProfileService profileService;
private final RuleQueryFactory ruleQueryFactory;
private final I18n i18n;

public BulkRuleActivationActions(QProfileService profileService, RuleQueryFactory ruleQueryFactory, I18n i18n) {
public BulkRuleActivationActions(QProfileService profileService, RuleQueryFactory ruleQueryFactory) {
this.profileService = profileService;
this.ruleQueryFactory = ruleQueryFactory;
this.i18n = i18n;
}

void define(WebService.NewController controller) {
@@ -63,12 +59,7 @@ public class BulkRuleActivationActions {
.setDescription("Bulk-activate rules on one or several Quality profiles")
.setPost(true)
.setSince("4.4")
.setHandler(new RequestHandler() {
@Override
public void handle(Request request, Response response) throws Exception {
bulkActivate(request, response);
}
});
.setHandler(this::bulkActivate);

defineRuleSearchParameters(activate);
defineProfileKeyParameter(activate);
@@ -84,12 +75,7 @@ public class BulkRuleActivationActions {
.setDescription("Bulk deactivate rules on Quality profiles")
.setPost(true)
.setSince("4.4")
.setHandler(new RequestHandler() {
@Override
public void handle(Request request, Response response) throws Exception {
bulkDeactivate(request, response);
}
});
.setHandler(this::bulkDeactivate);

defineRuleSearchParameters(deactivate);
defineProfileKeyParameter(deactivate);
@@ -117,11 +103,11 @@ public class BulkRuleActivationActions {
writeResponse(result, response);
}

private void writeResponse(BulkChangeResult result, Response response) {
private static void writeResponse(BulkChangeResult result, Response response) {
JsonWriter json = response.newJsonWriter().beginObject();
json.prop("succeeded", result.countSucceeded());
json.prop("failed", result.countFailed());
result.getErrors().writeJson(json, i18n);
result.getErrors().writeJson(json);
json.endObject().close();
}
}

+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java Vedi File

@@ -298,7 +298,7 @@ public class UserUpdater {
messages.add(Message.of(Validation.IS_TOO_LONG_MESSAGE, LOGIN_PARAM, LOGIN_MAX_LENGTH));
return false;
} else if (!login.matches("\\A\\w[\\w\\.\\-_@]+\\z")) {
messages.add(Message.of("user.bad_login"));
messages.add(Message.of("Use only letters, numbers, and .-_@ please."));
return false;
}
}
@@ -324,7 +324,7 @@ public class UserUpdater {

private static boolean checkPasswordChangeAllowed(UserDto userDto, List<Message> messages) {
if (!userDto.isLocal()) {
messages.add(Message.of("user.password_cant_be_changed_on_external_auth"));
messages.add(Message.of("Password cannot be changed when external authentication is used"));
return false;
}
return true;
@@ -343,7 +343,7 @@ public class UserUpdater {
boolean isValid = true;
for (String scmAccount : scmAccounts) {
if (scmAccount.equals(login) || scmAccount.equals(email)) {
messages.add(Message.of("user.login_or_email_used_as_scm_account"));
messages.add(Message.of("Login and email are automatically considered as SCM accounts"));
isValid = false;
} else {
List<UserDto> matchingUsers = dbClient.userDao().selectByScmAccountOrLoginOrEmail(dbSession, scmAccount);
@@ -355,7 +355,7 @@ public class UserUpdater {
matchingUsersWithoutExistingUser.add(matchingUser.getName() + " (" + matchingUser.getLogin() + ")");
}
if (!matchingUsersWithoutExistingUser.isEmpty()) {
messages.add(Message.of("user.scm_account_already_used", scmAccount, Joiner.on(", ").join(matchingUsersWithoutExistingUser)));
messages.add(Message.of("The scm account '%s' is already used by user(s) : '%s'", scmAccount, Joiner.on(", ").join(matchingUsersWithoutExistingUser)));
isValid = false;
}
}

+ 3
- 5
server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java Vedi File

@@ -19,14 +19,12 @@
*/
package org.sonar.server.util;

import java.util.List;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.PropertyType;
import org.sonar.server.exceptions.BadRequestException;

import javax.annotation.Nullable;

import java.util.List;

public class BooleanTypeValidation implements TypeValidation {

@Override
@@ -37,7 +35,7 @@ public class BooleanTypeValidation implements TypeValidation {
@Override
public void validate(String value, @Nullable List<String> options) {
if (!StringUtils.equalsIgnoreCase(value, "true") && !StringUtils.equalsIgnoreCase(value, "false")) {
throw new BadRequestException("errors.type.notBoolean", value);
throw new BadRequestException("Value '%s' must be one of \"true\" or \"false\".", value);
}
}


+ 3
- 4
server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java Vedi File

@@ -19,12 +19,11 @@
*/
package org.sonar.server.util;

import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.PropertyType;
import org.sonar.server.exceptions.BadRequestException;

import javax.annotation.Nullable;
import java.util.List;

public class FloatTypeValidation implements TypeValidation {

@Override
@@ -37,7 +36,7 @@ public class FloatTypeValidation implements TypeValidation {
try {
Double.parseDouble(value);
} catch (NumberFormatException e) {
throw new BadRequestException("errors.type.notFloat", value);
throw new BadRequestException("Value '%s' must be an floating point number.", value);
}
}


+ 3
- 5
server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java Vedi File

@@ -19,13 +19,11 @@
*/
package org.sonar.server.util;

import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.PropertyType;
import org.sonar.server.exceptions.BadRequestException;

import javax.annotation.Nullable;

import java.util.List;

public class IntegerTypeValidation implements TypeValidation {

@Override
@@ -38,7 +36,7 @@ public class IntegerTypeValidation implements TypeValidation {
try {
Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new BadRequestException("errors.type.notInteger", value);
throw new BadRequestException("Value '%s' must be an integer.", value);
}
}


+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java Vedi File

@@ -35,7 +35,7 @@ public class LongTypeValidation implements TypeValidation {
try {
Long.parseLong(value);
} catch (NumberFormatException e) {
throw new BadRequestException("errors.type.notLong", value);
throw new BadRequestException("Value '%s' must be a long.", value);
}
}
}

+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java Vedi File

@@ -36,7 +36,7 @@ public class MetricLevelTypeValidation implements TypeValidation {
try {
Metric.Level.valueOf(value);
} catch (IllegalArgumentException e) {
throw new BadRequestException("errors.type.notMetricLevel", value);
throw new BadRequestException("Value '%s' must be one of \"OK\", \"WARN\", \"ERROR\".", value);
}
}
}

+ 3
- 5
server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java Vedi File

@@ -19,14 +19,12 @@
*/
package org.sonar.server.util;

import java.util.List;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.PropertyType;
import org.sonar.server.exceptions.BadRequestException;

import javax.annotation.Nullable;

import java.util.List;

public class StringListTypeValidation implements TypeValidation {

@Override
@@ -38,7 +36,7 @@ public class StringListTypeValidation implements TypeValidation {
public void validate(String value, @Nullable List<String> options) {
if (options != null && !options.contains(value)) {
String optionsAsString = StringUtils.join(options, ", ");
throw new BadRequestException("errors.type.notInOptions", value, optionsAsString);
throw new BadRequestException("Value '%s' must be one of : %s.", value, optionsAsString);
}
}


+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/util/Validation.java Vedi File

@@ -24,10 +24,10 @@ import org.sonar.server.exceptions.BadRequestException;

public class Validation {

public static final String CANT_BE_EMPTY_MESSAGE = "errors.cant_be_empty";
public static final String IS_TOO_SHORT_MESSAGE = "errors.is_too_short";
public static final String IS_TOO_LONG_MESSAGE = "errors.is_too_long";
public static final String IS_ALREADY_USED_MESSAGE = "errors.is_already_used";
public static final String CANT_BE_EMPTY_MESSAGE = "%s can't be empty";
public static final String IS_TOO_SHORT_MESSAGE = "%s is too short (minimum is %s characters)";
public static final String IS_TOO_LONG_MESSAGE = "%s is too long (maximum is %s characters)";
public static final String IS_ALREADY_USED_MESSAGE = "%s has already been taken";

private Validation() {
// only static methods

+ 2
- 5
server/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java Vedi File

@@ -27,7 +27,6 @@ import java.util.Locale;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.picocontainer.Startable;
import org.sonar.api.i18n.I18n;
import org.sonar.api.server.ServerSide;
import org.sonar.api.server.ws.LocalConnector;
import org.sonar.api.server.ws.Request;
@@ -61,14 +60,12 @@ public class WebServiceEngine implements LocalConnector, Startable {
private static final Logger LOGGER = Loggers.get(WebServiceEngine.class);

private final WebService.Context context;
private final I18n i18n;

public WebServiceEngine(WebService[] webServices, I18n i18n) {
public WebServiceEngine(WebService[] webServices) {
context = new WebService.Context();
for (WebService webService : webServices) {
webService.define(context);
}
this.i18n = i18n;
}

@Override
@@ -143,7 +140,7 @@ public class WebServiceEngine implements LocalConnector, Startable {

try (JsonWriter json = JsonWriter.of(new OutputStreamWriter(stream.output(), StandardCharsets.UTF_8))) {
json.beginObject();
errors.writeJson(json, i18n);
errors.writeJson(json);
json.endObject();
} catch (Exception e) {
// Do not hide the potential exception raised in the try block.

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/authentication/SsoAuthenticatorTest.java Vedi File

@@ -344,7 +344,7 @@ public class SsoAuthenticatorTest {
setNotUserInToken();

expectedException.expect(authenticationException().from(Source.sso()).withoutLogin().andNoPublicMessage());
expectedException.expectMessage("user.bad_login");
expectedException.expectMessage("Use only letters, numbers, and .-_@ please.");
try {
underTest.authenticate(createRequest("invalid login", DEFAULT_NAME, DEFAULT_EMAIL, GROUPS), response);
} finally {

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/email/ws/SendActionTest.java Vedi File

@@ -110,7 +110,7 @@ public class SendActionTest {
executeRequest("john@doo.com", "Test Message from SonarQube", "This is a test message from SonarQube at http://localhost:9000");
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).extracting(Message::getKey).containsExactly(
assertThat(e.errors().messages()).extracting(Message::getMessage).containsExactly(
"root cause", "parent cause", "child cause", "last message");
}
}

+ 10
- 12
server/sonar-server/src/test/java/org/sonar/server/exceptions/MessageTest.java Vedi File

@@ -27,25 +27,23 @@ public class MessageTest {

@Test
public void create_message() {
Message message = Message.of("key1", "param1");
assertThat(message.getKey()).isEqualTo("key1");
assertThat(message.getParams()).containsOnly("param1");
Message message = Message.of("key1 %s", "param1");
assertThat(message.getMessage()).isEqualTo("key1 param1");
}

@Test
public void create_message_without_params() {
Message message = Message.of("key1");
assertThat(message.getKey()).isEqualTo("key1");
assertThat(message.getParams()).isEmpty();
assertThat(message.getMessage()).isEqualTo("key1");
}

@Test
public void test_equals_and_hashcode() throws Exception {
Message message1 = Message.of("key1", "param1");
Message message2 = Message.of("key2", "param2");
Message message1 = Message.of("key1%s", "param1");
Message message2 = Message.of("key2%s", "param2");
Message message3 = Message.of("key1");
Message message4 = Message.of("key1", "param2");
Message sameAsMessage1 = Message.of("key1", "param1");
Message message4 = Message.of("key1%s", "param2");
Message sameAsMessage1 = Message.of("key1%s", "param1");

assertThat(message1).isEqualTo(message1);
assertThat(message1).isNotEqualTo(message2);
@@ -64,8 +62,8 @@ public class MessageTest {

@Test
public void to_string() {
assertThat(Message.of("key1", "param1").toString()).isEqualTo("Message{key=key1, params=[param1]}");
assertThat(Message.of("key1").toString()).isEqualTo("Message{key=key1, params=[]}");
assertThat(Message.of("key1", null).toString()).isEqualTo("Message{key=key1, params=null}");
assertThat(Message.of("key1 %s", "param1").toString()).isEqualTo("key1 param1");
assertThat(Message.of("key1").toString()).isEqualTo("key1");
assertThat(Message.of("key1", null).toString()).isEqualTo("key1");
}
}

+ 13
- 11
server/sonar-server/src/test/java/org/sonar/server/exceptions/VerificationsTest.java Vedi File

@@ -19,24 +19,26 @@
*/
package org.sonar.server.exceptions;

import org.junit.Rule;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import org.junit.rules.ExpectedException;

public class VerificationsTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void check() {
// no exception
Verifications.check(true, "my.l10n.key", "foo", "bar");
Verifications.check(true, "Error on %s and %s", "foo", "bar");
}

@Test
public void fail() throws Exception {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Error on foo and bar");

try {
Verifications.check(false, "my.l10n.key", "foo", "bar");
fail();
} catch (BadRequestException e) {
assertThat(e.firstError().getKey()).isEqualTo("my.l10n.key");
assertThat(e.firstError().getParams()).containsOnly("foo", "bar");
}
Verifications.check(false, "Error on %s and %s", "foo", "bar");
}
}

+ 3
- 4
server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java Vedi File

@@ -30,7 +30,6 @@ import org.sonar.db.DbTester;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;

import static java.lang.String.format;
import static org.assertj.core.api.Java6Assertions.assertThat;

public class QualityGateUpdaterTest {
@@ -44,7 +43,7 @@ public class QualityGateUpdaterTest {
public DbTester db = DbTester.create(System2.INSTANCE);

DbClient dbClient = db.getDbClient();
DbSession dbSession= db.getSession();
DbSession dbSession = db.getSession();

QualityGateUpdater underTest = new QualityGateUpdater(dbClient);

@@ -62,7 +61,7 @@ public class QualityGateUpdaterTest {
@Test
public void fail_to_create_when_name_is_empty() throws Exception {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("errors.cant_be_empty", "Name"));
expectedException.expectMessage("Name can't be empty");
underTest.create(dbSession, "");
}

@@ -71,7 +70,7 @@ public class QualityGateUpdaterTest {
dbClient.qualityGateDao().insert(new QualityGateDto().setName(QGATE_NAME));

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("errors.is_already_used");
expectedException.expectMessage("Name has already been taken");
underTest.create(dbSession, QGATE_NAME);
}
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java Vedi File

@@ -497,7 +497,7 @@ public class RuleActivatorMediumTest {
fail();
} catch (BadRequestException e) {
Message msg = e.errors().messages().get(0);
assertThat(msg.getKey()).isEqualTo("errors.type.notInteger");
assertThat(msg.getMessage()).isEqualTo("Value 'foo' must be an integer.");
verifyZeroActiveRules(XOO_P1_KEY);
}
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java Vedi File

@@ -63,7 +63,7 @@ public class QProfilesWsTest {

controller = new WsTester(new QProfilesWs(
new RuleActivationActions(profileService),
new BulkRuleActivationActions(profileService, null, i18n),
new BulkRuleActivationActions(profileService, null),
new AddProjectAction(projectAssociationParameters, null, null, dbClient),
new RemoveProjectAction(projectAssociationParameters, null, null, dbClient),
new CreateAction(null, null, null, languages, importers, userSessionRule, null),

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/rule/RuleCreatorMediumTest.java Vedi File

@@ -215,7 +215,7 @@ public class RuleCreatorMediumTest {
creator.create(newRule);
Fail.failBecauseExceptionWasNotThrown(BadRequestException.class);
} catch (BadRequestException iae) {
assertThat(iae).hasMessage("errors.type.notInteger");
assertThat(iae).hasMessage("Value 'polop' must be an integer.");
}

dbSession.clearCache();

+ 178
- 240
server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterTest.java Vedi File

@@ -27,6 +27,7 @@ import org.elasticsearch.search.SearchHit;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.sonar.api.config.MapSettings;
import org.sonar.api.config.Settings;
@@ -35,20 +36,15 @@ import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.user.GroupDao;
import org.sonar.db.user.GroupTesting;
import org.sonar.db.user.UserDao;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserTesting;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.Message;
import org.sonar.server.exceptions.ServerException;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.user.index.UserIndexDefinition;
import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.util.Validation;

import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
@@ -68,10 +64,13 @@ public class UserUpdaterTest {
private static final long PAST = 1000000000000L;
private static final String DEFAULT_LOGIN = "marius";

private System2 system2 = mock(System2.class);

@Rule
public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
public ExpectedException expectedException = ExpectedException.none();

private System2 system2 = mock(System2.class);
@Rule
public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));

@Rule
public DbTester db = DbTester.create(system2);
@@ -80,19 +79,12 @@ public class UserUpdaterTest {
private NewUserNotifier newUserNotifier = mock(NewUserNotifier.class);
private ArgumentCaptor<NewUserHandler.Context> newUserHandler = ArgumentCaptor.forClass(NewUserHandler.Context.class);
private Settings settings = new MapSettings();
private UserDao userDao = dbClient.userDao();
private GroupDao groupDao = dbClient.groupDao();
private DbSession session = db.getSession();
private UserIndexer userIndexer;
private UserUpdater underTest;
private UserIndexer userIndexer = new UserIndexer(system2, dbClient, es.client());
private UserUpdater underTest = new UserUpdater(newUserNotifier, settings, dbClient, userIndexer, system2, TestDefaultOrganizationProvider.from(db));

@Before
public void setUp() {
userIndexer = new UserIndexer(system2, dbClient, es.client());
DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
underTest = new UserUpdater(newUserNotifier, settings, dbClient,
userIndexer, system2, defaultOrganizationProvider);

when(system2.now()).thenReturn(NOW);
}

@@ -107,7 +99,7 @@ public class UserUpdaterTest {
.setPassword("PASSWORD")
.setScmAccounts(ImmutableList.of("u1", "u_1", "User 1")));

UserDto dto = userDao.selectByLogin(session, "user");
UserDto dto = dbClient.userDao().selectByLogin(session, "user");
assertThat(dto.getId()).isNotNull();
assertThat(dto.getLogin()).isEqualTo("user");
assertThat(dto.getName()).isEqualTo("User");
@@ -140,7 +132,7 @@ public class UserUpdaterTest {
.setName("User")
.setPassword("password"));

UserDto dto = userDao.selectByLogin(session, "user");
UserDto dto = dbClient.userDao().selectByLogin(session, "user");
assertThat(dto.getExternalIdentity()).isEqualTo("user");
assertThat(dto.getExternalIdentityProvider()).isEqualTo("sonarqube");
assertThat(dto.isLocal()).isTrue();
@@ -156,7 +148,7 @@ public class UserUpdaterTest {
.setPassword("password")
.setExternalIdentity(new ExternalIdentity("github", "user")));

UserDto dto = userDao.selectByLogin(session, "ABCD");
UserDto dto = dbClient.userDao().selectByLogin(session, "ABCD");
assertThat(dto.getExternalIdentity()).isEqualTo("user");
assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
assertThat(dto.isLocal()).isFalse();
@@ -171,7 +163,7 @@ public class UserUpdaterTest {
.setLogin("us")
.setName("User"));

UserDto dto = userDao.selectByLogin(session, "us");
UserDto dto = dbClient.userDao().selectByLogin(session, "us");
assertThat(dto.getId()).isNotNull();
assertThat(dto.getLogin()).isEqualTo("us");
assertThat(dto.getName()).isEqualTo("User");
@@ -191,7 +183,7 @@ public class UserUpdaterTest {
.setPassword("password")
.setScmAccounts(newArrayList("u1", "", null)));

assertThat(userDao.selectByLogin(session, "user").getScmAccountsAsList()).containsOnly("u1");
assertThat(dbClient.userDao().selectByLogin(session, "user").getScmAccountsAsList()).containsOnly("u1");
}

@Test
@@ -205,7 +197,7 @@ public class UserUpdaterTest {
.setPassword("password")
.setScmAccounts(newArrayList("")));

assertThat(userDao.selectByLogin(session, "user").getScmAccounts()).isNull();
assertThat(dbClient.userDao().selectByLogin(session, "user").getScmAccounts()).isNull();
}

@Test
@@ -219,119 +211,103 @@ public class UserUpdaterTest {
.setPassword("password")
.setScmAccounts(newArrayList("u1", "u1")));

assertThat(userDao.selectByLogin(session, "user").getScmAccountsAsList()).containsOnly("u1");
assertThat(dbClient.userDao().selectByLogin(session, "user").getScmAccountsAsList()).containsOnly("u1");
}

@Test
public void fail_to_create_user_with_missing_login() {
try {
underTest.create(NewUser.create()
.setLogin(null)
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of(Validation.CANT_BE_EMPTY_MESSAGE, "Login"));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login can't be empty");

underTest.create(NewUser.create()
.setLogin(null)
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_invalid_login() {
try {
underTest.create(NewUser.create()
.setLogin("/marius/")
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.bad_login"));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Use only letters, numbers, and .-_@ please.");

underTest.create(NewUser.create()
.setLogin("/marius/")
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_space_in_login() {
try {
underTest.create(NewUser.create()
.setLogin("mari us")
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.bad_login"));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Use only letters, numbers, and .-_@ please.");

underTest.create(NewUser.create()
.setLogin("mari us")
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_too_short_login() {
try {
underTest.create(NewUser.create()
.setLogin("m")
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of(Validation.IS_TOO_SHORT_MESSAGE, "Login", 2));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login is too short (minimum is 2 characters)");

underTest.create(NewUser.create()
.setLogin("m")
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_too_long_login() {
try {
underTest.create(NewUser.create()
.setLogin(Strings.repeat("m", 256))
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of(Validation.IS_TOO_LONG_MESSAGE, "Login", 255));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login is too long (maximum is 255 characters)");

underTest.create(NewUser.create()
.setLogin(Strings.repeat("m", 256))
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_missing_name() {
try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName(null)
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of(Validation.CANT_BE_EMPTY_MESSAGE, "Name"));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Name can't be empty");

underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName(null)
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_too_long_name() {
try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName(Strings.repeat("m", 201))
.setEmail("marius@mail.com")
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of(Validation.IS_TOO_LONG_MESSAGE, "Name", 200));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Name is too long (maximum is 200 characters)");

underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName(Strings.repeat("m", 201))
.setEmail("marius@mail.com")
.setPassword("password"));
}

@Test
public void fail_to_create_user_with_too_long_email() {
try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius")
.setEmail(Strings.repeat("m", 101))
.setPassword("password"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of(Validation.IS_TOO_LONG_MESSAGE, "Email", 100));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Email is too long (maximum is 100 characters)");

underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius")
.setEmail(Strings.repeat("m", 101))
.setPassword("password"));
}

@Test
@@ -351,65 +327,55 @@ public class UserUpdaterTest {
@Test
public void fail_to_create_user_when_scm_account_is_already_used() {
db.prepareDbUnit(getClass(), "fail_to_create_user_when_scm_account_is_already_used.xml");
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("The scm account 'jo' is already used by user(s) : 'John (john)'");

try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("jo")));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.scm_account_already_used", "jo", "John (john)"));
}
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("jo")));
}

@Test
public void fail_to_create_user_when_scm_account_is_already_used_by_many_user() {
db.prepareDbUnit(getClass(), "fail_to_create_user_when_scm_account_is_already_used_by_many_user.xml");
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("The scm account 'john@email.com' is already used by user(s) : 'John (john), Technical account (technical-account)'");

try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("john@email.com")));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.scm_account_already_used", "john@email.com", "John (john), Technical account (technical-account)"));
}
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius")
.setEmail("marius@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("john@email.com")));
}

@Test
public void fail_to_create_user_when_scm_account_is_user_login() {
try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2")
.setScmAccounts(newArrayList(DEFAULT_LOGIN)));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.login_or_email_used_as_scm_account"));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login and email are automatically considered as SCM accounts");

underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2")
.setScmAccounts(newArrayList(DEFAULT_LOGIN)));
}

@Test
public void fail_to_create_user_when_scm_account_is_user_email() {
try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2")
.setScmAccounts(newArrayList("marius2@mail.com")));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.login_or_email_used_as_scm_account"));
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login and email are automatically considered as SCM accounts");

underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2")
.setScmAccounts(newArrayList("marius2@mail.com")));
}

@Test
@@ -445,36 +411,31 @@ public class UserUpdaterTest {
}

@Test
public void fail_to_associate_default_group_to_user_if_no_default_group() {
public void doest_not_fail_when_no_default_group() {
settings.setProperty(CORE_DEFAULT_GROUP, (String) null);

try {
underTest.create(NewUser.create()
.setLogin("user")
.setName("User")
.setEmail("user@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("u1", "u_1")));
} catch (Exception e) {
assertThat(e).isInstanceOf(ServerException.class).hasMessage("The default group property 'sonar.defaultGroup' is null");
}
underTest.create(NewUser.create()
.setLogin("user")
.setName("User")
.setEmail("user@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("u1", "u_1")));

assertThat(dbClient.userDao().selectByLogin(session, "user")).isNotNull();
}

@Test
public void fail_to_associate_default_group_when_default_group_does_not_exist() {
settings.setProperty(CORE_DEFAULT_GROUP, "polop");
expectedException.expect(ServerException.class);
expectedException.expectMessage("The default group 'polop' for new users does not exist. Please update the general security settings to fix this issue.");

try {
underTest.create(NewUser.create()
.setLogin("user")
.setName("User")
.setEmail("user@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("u1", "u_1")));
} catch (Exception e) {
assertThat(e).isInstanceOf(ServerException.class)
.hasMessage("The default group 'polop' for new users does not exist. Please update the general security settings to fix this issue.");
}
underTest.create(NewUser.create()
.setLogin("user")
.setName("User")
.setEmail("user@mail.com")
.setPassword("password")
.setScmAccounts(newArrayList("u1", "u_1")));
}

@Test
@@ -492,7 +453,7 @@ public class UserUpdaterTest {
.setPassword("password2"));
session.commit();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.isActive()).isTrue();
assertThat(dto.getName()).isEqualTo("Marius2");
assertThat(dto.getEmail()).isEqualTo("marius2@mail.com");
@@ -519,7 +480,7 @@ public class UserUpdaterTest {
.setEmail("marius2@mail.com"));
session.commit();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.isActive()).isTrue();
assertThat(dto.getName()).isEqualTo("Marius2");
assertThat(dto.getEmail()).isEqualTo("marius2@mail.com");
@@ -548,7 +509,7 @@ public class UserUpdaterTest {
.setExternalIdentity(new ExternalIdentity("github", "john")));
session.commit();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getExternalIdentity()).isEqualTo("john");
assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
assertThat(dto.isLocal()).isFalse();
@@ -558,17 +519,14 @@ public class UserUpdaterTest {
public void fail_to_reactivate_user_if_not_disabled() {
db.prepareDbUnit(getClass(), "fail_to_reactivate_user_if_not_disabled.xml");
createDefaultGroup();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("An active user with login 'marius' already exists");

try {
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2"));
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("An active user with login 'marius' already exists");
}
underTest.create(NewUser.create()
.setLogin(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2"));
}

@Test
@@ -601,7 +559,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.isActive()).isTrue();
assertThat(dto.getName()).isEqualTo("Marius2");
assertThat(dto.getEmail()).isEqualTo("marius2@mail.com");
@@ -636,7 +594,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getExternalIdentity()).isEqualTo("john");
assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
assertThat(dto.getUpdatedAt()).isEqualTo(NOW);
@@ -657,7 +615,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getExternalIdentity()).isEqualTo("john");
assertThat(dto.getExternalIdentityProvider()).isEqualTo("github");
// Password must be removed
@@ -680,7 +638,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.isActive()).isTrue();
assertThat(dto.getName()).isEqualTo("Marius2");
assertThat(dto.getEmail()).isEqualTo("marius2@mail.com");
@@ -713,7 +671,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getScmAccountsAsList()).containsOnly("ma2");
}

@@ -727,7 +685,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getName()).isEqualTo("Marius2");

// Following fields has not changed
@@ -747,7 +705,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getEmail()).isEqualTo("marius2@mail.com");

// Following fields has not changed
@@ -767,7 +725,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getScmAccountsAsList()).containsOnly("ma2");

// Following fields has not changed
@@ -787,7 +745,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getScmAccountsAsList()).containsOnly("ma", "marius33");
}

@@ -801,7 +759,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getScmAccounts()).isNull();
}

@@ -815,7 +773,7 @@ public class UserUpdaterTest {
session.commit();
session.clearCache();

UserDto dto = userDao.selectByLogin(session, DEFAULT_LOGIN);
UserDto dto = dbClient.userDao().selectByLogin(session, DEFAULT_LOGIN);
assertThat(dto.getSalt()).isNotEqualTo("79bd6a8e79fb8c76ac8b121cc7e8e11ad1af8365");
assertThat(dto.getCryptedPassword()).isNotEqualTo("650d2261c98361e2f67f90ce5c65a95e7d8ea2fg");

@@ -829,13 +787,10 @@ public class UserUpdaterTest {
public void fail_to_set_null_password_when_local_user() {
addUser(UserTesting.newLocalUser(DEFAULT_LOGIN, "Marius", "marius@email.com"));
createDefaultGroup();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Password can't be empty");

try {
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setPassword(null));
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("errors.cant_be_empty", "Password"));
}
underTest.update(UpdateUser.create(DEFAULT_LOGIN).setPassword(null));
}

@Test
@@ -843,16 +798,13 @@ public class UserUpdaterTest {
UserDto user = newUserDto()
.setLogin(DEFAULT_LOGIN)
.setLocal(false);
userDao.insert(session, user);
dbClient.userDao().insert(session, user);
session.commit();
createDefaultGroup();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Password cannot be changed when external authentication is used");

try {
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setPassword("password2"));
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.password_cant_be_changed_on_external_auth"));
}
underTest.update(UpdateUser.create(DEFAULT_LOGIN).setPassword("password2"));
}

@Test
@@ -898,70 +850,56 @@ public class UserUpdaterTest {
public void fail_to_update_user_when_scm_account_is_already_used() {
db.prepareDbUnit(getClass(), "fail_to_update_user_when_scm_account_is_already_used.xml");
createDefaultGroup();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("The scm account 'jo' is already used by user(s) : 'John (john)'");

try {
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2")
.setScmAccounts(newArrayList("jo")));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.scm_account_already_used", "jo", "John (john)"));
}
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setName("Marius2")
.setEmail("marius2@mail.com")
.setPassword("password2")
.setScmAccounts(newArrayList("jo")));
}

@Test
public void fail_to_update_user_when_scm_account_is_user_login() {
db.prepareDbUnit(getClass(), "update_user.xml");
createDefaultGroup();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login and email are automatically considered as SCM accounts");

try {
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setScmAccounts(newArrayList(DEFAULT_LOGIN)));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.login_or_email_used_as_scm_account"));
}
underTest.update(UpdateUser.create(DEFAULT_LOGIN).setScmAccounts(newArrayList(DEFAULT_LOGIN)));
}

@Test
public void fail_to_update_user_when_scm_account_is_existing_user_email() {
db.prepareDbUnit(getClass(), "update_user.xml");
createDefaultGroup();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login and email are automatically considered as SCM accounts");

try {
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setScmAccounts(newArrayList("marius@lesbronzes.fr")));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.login_or_email_used_as_scm_account"));
}
underTest.update(UpdateUser.create(DEFAULT_LOGIN).setScmAccounts(newArrayList("marius@lesbronzes.fr")));
}

@Test
public void fail_to_update_user_when_scm_account_is_new_user_email() {
db.prepareDbUnit(getClass(), "update_user.xml");
createDefaultGroup();
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Login and email are automatically considered as SCM accounts");

try {
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setEmail("marius@newmail.com")
.setScmAccounts(newArrayList("marius@newmail.com")));
fail();
} catch (BadRequestException e) {
assertThat(e.errors().messages()).containsOnly(Message.of("user.login_or_email_used_as_scm_account"));
}
underTest.update(UpdateUser.create(DEFAULT_LOGIN)
.setEmail("marius@newmail.com")
.setScmAccounts(newArrayList("marius@newmail.com")));
}

private void createDefaultGroup() {
settings.setProperty(CORE_DEFAULT_GROUP, "sonar-users");
groupDao.insert(session, GroupTesting.newGroupDto().setName("sonar-users").setOrganizationUuid(db.getDefaultOrganization().getUuid()));
dbClient.groupDao().insert(session, GroupTesting.newGroupDto().setName("sonar-users").setOrganizationUuid(db.getDefaultOrganization().getUuid()));
session.commit();
}

private UserDto addUser(UserDto user) {
userDao.insert(session, user);
dbClient.userDao().insert(session, user);
session.commit();
return user;
}

+ 14
- 20
server/sonar-server/src/test/java/org/sonar/server/util/BooleanTypeValidationTest.java Vedi File

@@ -19,45 +19,39 @@
*/
package org.sonar.server.util;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.server.exceptions.BadRequestException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class BooleanTypeValidationTest {

BooleanTypeValidation validation;
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
public void setUp() {
validation = new BooleanTypeValidation();
}
private BooleanTypeValidation underTest = new BooleanTypeValidation();

@Test
public void key() {
assertThat(validation.key()).isEqualTo("BOOLEAN");
assertThat(underTest.key()).isEqualTo("BOOLEAN");
}

@Test
public void not_fail_on_valid_boolean() {
validation.validate("true", null);
validation.validate("True", null);
validation.validate("false", null);
validation.validate("FALSE", null);
underTest.validate("true", null);
underTest.validate("True", null);
underTest.validate("false", null);
underTest.validate("FALSE", null);
}

@Test
public void fail_on_invalid_boolean() {
try {
validation.validate("abc", null);
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(BadRequestException.class);
BadRequestException badRequestException = (BadRequestException) e;
assertThat(badRequestException.firstError().getParams()[0]).isEqualTo("abc");
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value 'abc' must be one of \"true\" or \"false\".");

underTest.validate("abc", null);
}

}

+ 9
- 15
server/sonar-server/src/test/java/org/sonar/server/util/FloatTypeValidationTest.java Vedi File

@@ -19,21 +19,19 @@
*/
package org.sonar.server.util;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.server.exceptions.BadRequestException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class FloatTypeValidationTest {

FloatTypeValidation validation;
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
public void setUp() {
validation = new FloatTypeValidation();
}
private FloatTypeValidation validation = new FloatTypeValidation();

@Test
public void key() {
@@ -49,14 +47,10 @@ public class FloatTypeValidationTest {

@Test
public void fail_on_invalid_float() {
try {
validation.validate("abc", null);
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(BadRequestException.class);
BadRequestException badRequestException = (BadRequestException) e;
assertThat(badRequestException.firstError().getParams()[0]).isEqualTo("abc");
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value 'abc' must be an floating point number.");

validation.validate("abc", null);
}

}

+ 13
- 23
server/sonar-server/src/test/java/org/sonar/server/util/IntegerTypeValidationTest.java Vedi File

@@ -19,21 +19,19 @@
*/
package org.sonar.server.util;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.server.exceptions.BadRequestException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class IntegerTypeValidationTest {

IntegerTypeValidation validation;
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
public void setUp() {
validation = new IntegerTypeValidation();
}
private IntegerTypeValidation validation = new IntegerTypeValidation();

@Test
public void key() {
@@ -48,26 +46,18 @@ public class IntegerTypeValidationTest {

@Test
public void fail_on_string() {
try {
validation.validate("abc", null);
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(BadRequestException.class);
BadRequestException badRequestException = (BadRequestException) e;
assertThat(badRequestException.firstError().getParams()[0]).isEqualTo("abc");
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value 'abc' must be an integer.");

validation.validate("abc", null);
}

@Test
public void fail_on_float() {
try {
validation.validate("10.1", null);
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(BadRequestException.class);
BadRequestException badRequestException = (BadRequestException) e;
assertThat(badRequestException.firstError().getParams()[0]).isEqualTo("10.1");
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value '10.1' must be an integer.");

validation.validate("10.1", null);
}

}

+ 2
- 0
server/sonar-server/src/test/java/org/sonar/server/util/LongTypeValidationTest.java Vedi File

@@ -47,6 +47,7 @@ public class LongTypeValidationTest {
@Test
public void fail_when_float() {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value '3.14' must be a long.");

underTest.validate("3.14", null);
}
@@ -54,6 +55,7 @@ public class LongTypeValidationTest {
@Test
public void fail_when_string() {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value 'original string' must be a long.");

underTest.validate("original string", null);
}

+ 9
- 16
server/sonar-server/src/test/java/org/sonar/server/util/StringListTypeValidationTest.java Vedi File

@@ -19,22 +19,20 @@
*/
package org.sonar.server.util;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.server.exceptions.BadRequestException;

import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class StringListTypeValidationTest {

StringListTypeValidation validation;
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
public void setUp() {
validation = new StringListTypeValidation();
}
private StringListTypeValidation validation = new StringListTypeValidation();

@Test
public void key() {
@@ -49,15 +47,10 @@ public class StringListTypeValidationTest {

@Test
public void fail_on_invalid_option() {
try {
validation.validate("abc", newArrayList("a", "b", "c"));
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(BadRequestException.class);
BadRequestException badRequestException = (BadRequestException) e;
assertThat(badRequestException.firstError().getParams()[0]).isEqualTo("abc");
assertThat(badRequestException.firstError().getParams()[1]).isEqualTo("a, b, c");
}
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Value 'abc' must be one of : a, b, c.");

validation.validate("abc", newArrayList("a", "b", "c"));
}

}

+ 4
- 2
server/sonar-server/src/test/java/org/sonar/server/util/TypeValidationsTest.java Vedi File

@@ -25,7 +25,9 @@ import org.sonar.server.exceptions.BadRequestException;
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TypeValidationsTest {

@@ -63,7 +65,7 @@ public class TypeValidationsTest {
} catch (Exception e) {
assertThat(e).isInstanceOf(BadRequestException.class);
BadRequestException badRequestException = (BadRequestException) e;
assertThat(badRequestException.firstError().getKey()).isEqualTo("Type 'Unknown' is not valid.");
assertThat(badRequestException.firstError().getMessage()).isEqualTo("Type 'Unknown' is not valid.");
}
}


+ 7
- 38
server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java Vedi File

@@ -20,7 +20,6 @@
package org.sonar.server.ws;

import java.io.IOException;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.commons.io.IOUtils;
@@ -29,7 +28,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.i18n.I18n;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.internal.ValidatingRequest;
@@ -55,8 +53,7 @@ public class WebServiceEngineTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();

private I18n i18n = mock(I18n.class);
private WebServiceEngine underTest = new WebServiceEngine(new WebService[] {new SystemWs()}, i18n);
private WebServiceEngine underTest = new WebServiceEngine(new WebService[] {new SystemWs()});

@Before
public void start() {
@@ -260,15 +257,14 @@ public class WebServiceEngineTest {
}

@Test
public void bad_request_with_i18n_message() {
ValidatingRequest request = new TestRequest().setMethod("GET").setPath("/api/system/fail_with_i18n_message").setParam("count", "3");
public void bad_request() {
ValidatingRequest request = new TestRequest().setMethod("GET").setPath("/api/system/fail_bad_request").setParam("count", "3");
DumbResponse response = new DumbResponse();
when(i18n.message(Locale.ENGLISH, "bad.request.reason", "bad.request.reason", 0)).thenReturn("reason #0");

underTest.execute(request, response);

assertThat(response.stream().outputAsString()).isEqualTo(
"{\"errors\":[{\"msg\":\"reason #0\"}]}");
"{\"errors\":[{\"msg\":\"Bad request !\"}]}");
assertThat(response.stream().status()).isEqualTo(400);
assertThat(response.stream().mediaType()).isEqualTo(MediaTypes.JSON);
}
@@ -289,24 +285,6 @@ public class WebServiceEngineTest {
assertThat(response.stream().mediaType()).isEqualTo(MediaTypes.JSON);
}

@Test
public void bad_request_with_multiple_i18n_messages() {
ValidatingRequest request = new TestRequest().setMethod("GET").setPath("/api/system/fail_with_multiple_i18n_messages").setParam("count", "3");
DumbResponse response = new DumbResponse();
when(i18n.message(Locale.ENGLISH, "bad.request.reason", "bad.request.reason", 0)).thenReturn("reason #0");
when(i18n.message(Locale.ENGLISH, "bad.request.reason", "bad.request.reason", 1)).thenReturn("reason #1");
when(i18n.message(Locale.ENGLISH, "bad.request.reason", "bad.request.reason", 2)).thenReturn("reason #2");

underTest.execute(request, response);

assertThat(response.stream().outputAsString()).isEqualTo("{\"errors\":[" +
"{\"msg\":\"reason #0\"}," +
"{\"msg\":\"reason #1\"}," +
"{\"msg\":\"reason #2\"}]}");
assertThat(response.stream().status()).isEqualTo(400);
assertThat(response.stream().mediaType()).isEqualTo(MediaTypes.JSON);
}

@Test
public void render_real_exception_when_failing_to_write_json_errors() {
ValidatingRequest request = new TestRequest().setMethod("GET").setPath("/api/system/fail_to_write_errors");
@@ -366,9 +344,9 @@ public class WebServiceEngineTest {
.setHandler((request, response) -> {
throw new IllegalStateException("Unexpected");
});
createNewDefaultAction(newController, "fail_with_i18n_message")
createNewDefaultAction(newController, "fail_bad_request")
.setHandler((request, response) -> {
throw new BadRequestException("bad.request.reason", 0);
throw new BadRequestException("Bad request !");
});
createNewDefaultAction(newController, "fail_with_multiple_messages")
.createParam("count", "Number of error messages to generate")
@@ -379,20 +357,11 @@ public class WebServiceEngineTest {
}
throw new BadRequestException(errors);
});
createNewDefaultAction(newController, "fail_with_multiple_i18n_messages")
.createParam("count", "Number of error messages to generate")
.setHandler((request, response) -> {
Errors errors = new Errors();
for (int count = 0; count < Integer.valueOf(request.param("count")); count++) {
errors.add(Message.of("bad.request.reason", count));
}
throw new BadRequestException(errors);
});
createNewDefaultAction(newController, "fail_to_write_errors")
.setHandler((request, response) -> {
Errors errors = mock(Errors.class);
// Try to simulate an error when generating JSON errors
doThrow(new IllegalArgumentException("Error!")).when(errors).writeJson(any(JsonWriter.class), any(I18n.class));
doThrow(new IllegalArgumentException("Error!")).when(errors).writeJson(any(JsonWriter.class));
throw new BadRequestException(errors);
});
createNewDefaultAction(newController, "alive")

+ 0
- 18
sonar-core/src/main/resources/org/sonar/l10n/core.properties Vedi File

@@ -2370,24 +2370,6 @@ permission_templates.project_creators.explanation=When a new project is created,
permission_templates.grant_permission_to_project_creators=Grant the "{0}" permission to project creators


#------------------------------------------------------------------------------
#
# ERRORS HANDLING
#
#------------------------------------------------------------------------------
errors.is_too_short={0} is too short (minimum is {1} characters)
errors.is_too_long={0} is too long (maximum is {1} characters)
errors.is_already_used={0} has already been taken
errors.cant_be_empty={0} can't be empty
errors.is_not_valid={0} is not valid

errors.type.notBoolean=Value '{0}' must be one of "true" or "false".
errors.type.notInteger=Value '{0}' must be an integer.
errors.type.notLong=Value '{0}' must be a long.
errors.type.notFloat=Value '{0}' must be an floating point number.
errors.type.notInOptions=Value '{0}' must be one of : {1}.
errors.type.notMetricLevel=Value '{0}' must be one of "OK", "WARN", "ERROR".

#------------------------------------------------------------------------------
#
# HELP

Loading…
Annulla
Salva