@@ -233,7 +233,7 @@ public class ComponentKeyUpdaterDao implements Dao { | |||
private static void checkNewNameOfAllModules(Set<ResourceDto> modules, String stringToReplace, String replacementString, ComponentKeyUpdaterMapper mapper) { | |||
for (ResourceDto module : modules) { | |||
String newKey = computeNewKey(module.getKey(), stringToReplace, replacementString); | |||
checkArgument(isValidProjectKey(newKey), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", newKey); | |||
checkProjectKey(newKey); | |||
if (mapper.countResourceByKey(newKey) > 0) { | |||
throw new IllegalArgumentException("Impossible to update key: a component with key \"" + newKey + "\" already exists."); | |||
} |
@@ -314,9 +314,9 @@ public class ComponentKeyUpdaterDaoTest { | |||
ComponentDto project = db.components().insertPrivateProject(); | |||
thrown.expect(IllegalArgumentException.class); | |||
thrown.expectMessage("Malformed key for 'my?project?key'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
thrown.expectMessage("Malformed key for ' '. Project key cannot be empty nor contain whitespaces."); | |||
underTest.bulkUpdateKey(dbSession, project.uuid(), project.getDbKey(), "my?project?key", doNotReturnAnyRekeyedResource()); | |||
underTest.bulkUpdateKey(dbSession, project.uuid(), project.getDbKey(), " ", doNotReturnAnyRekeyedResource()); | |||
} | |||
@Test | |||
@@ -377,7 +377,7 @@ public class ComponentKeyUpdaterDaoTest { | |||
thrown.expect(IllegalArgumentException.class); | |||
underTest.simulateBulkUpdateKey(dbSession, "A", "project", "project?"); | |||
underTest.simulateBulkUpdateKey(dbSession, "A", "project", " "); | |||
} | |||
@Test |
@@ -102,7 +102,7 @@ public class ComponentService { | |||
} | |||
private static void checkProjectOrModuleKeyFormat(String key) { | |||
checkRequest(isValidProjectKey(key), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", key); | |||
checkRequest(isValidProjectKey(key), "Malformed key for '%s'. It cannot be empty nor contain whitespaces.", key); | |||
} | |||
} |
@@ -163,8 +163,7 @@ public class ComponentUpdater { | |||
} | |||
private void checkKeyFormat(String qualifier, String key) { | |||
checkRequest(isValidProjectKey(key), | |||
"Malformed key for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", getQualifierToDisplay(qualifier), key); | |||
checkRequest(isValidProjectKey(key), "Malformed key for %s: '%s'. It cannot be empty nor contain whitespaces.", getQualifierToDisplay(qualifier), key); | |||
} | |||
private void checkLegacyBranchFormat(String qualifier, @Nullable String branch) { |
@@ -153,20 +153,20 @@ public class ComponentServiceUpdateKeyTest { | |||
logInAsProjectAdministrator(project); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Malformed key for ''. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
expectedException.expectMessage("Malformed key for ''. It cannot be empty nor contain whitespaces."); | |||
underTest.updateKey(dbSession, project, ""); | |||
} | |||
@Test | |||
public void fail_if_new_key_is_not_formatted_correctly() { | |||
public void fail_if_new_key_is_invalid() { | |||
ComponentDto project = insertSampleRootProject(); | |||
logInAsProjectAdministrator(project); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Malformed key for 'sample?root'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
expectedException.expectMessage("Malformed key for 'sample root'. It cannot be empty nor contain whitespaces."); | |||
underTest.updateKey(dbSession, project, "sample?root"); | |||
underTest.updateKey(dbSession, project, "sample root"); | |||
} | |||
@Test |
@@ -304,11 +304,11 @@ public class ComponentUpdaterTest { | |||
@Test | |||
public void fail_when_key_has_bad_format() { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Malformed key for Project: 1234"); | |||
expectedException.expectMessage("Malformed key for Project: ' '"); | |||
underTest.create(db.getSession(), | |||
NewComponent.newComponentBuilder() | |||
.setKey("1234") | |||
.setKey(" ") | |||
.setName(DEFAULT_PROJECT_NAME) | |||
.setOrganizationUuid(db.getDefaultOrganization().getUuid()) | |||
.build(), | |||
@@ -318,11 +318,11 @@ public class ComponentUpdaterTest { | |||
@Test | |||
public void properly_fail_when_key_contains_percent_character() { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Malformed key for Project: project%Key"); | |||
expectedException.expectMessage("Malformed key for Project: ' '"); | |||
underTest.create(db.getSession(), | |||
NewComponent.newComponentBuilder() | |||
.setKey("project%Key") | |||
.setKey(" ") | |||
.setName(DEFAULT_PROJECT_NAME) | |||
.setOrganizationUuid(db.getDefaultOrganization().getUuid()) | |||
.build(), |
@@ -183,9 +183,9 @@ public class BulkUpdateKeyActionTest { | |||
insertMyProject(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
expectedException.expectMessage("Malformed key for 'my aproject'. Project key cannot be empty nor contain whitespaces."); | |||
callByKey(MY_PROJECT_KEY, FROM, "my?"); | |||
callByKey(MY_PROJECT_KEY, FROM, "my a"); | |||
} | |||
@Test | |||
@@ -193,9 +193,9 @@ public class BulkUpdateKeyActionTest { | |||
insertMyProject(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
expectedException.expectMessage("Malformed key for 'my aproject'. Project key cannot be empty nor contain whitespaces."); | |||
callDryRunByKey(MY_PROJECT_KEY, FROM, "my?"); | |||
callDryRunByKey(MY_PROJECT_KEY, FROM, "my a"); | |||
} | |||
@Test |
@@ -305,14 +305,14 @@ public class CreateActionTest { | |||
} | |||
@Test | |||
public void properly_fail_when_project_key_contains_percent_character() { | |||
public void properly_fail_when_invalid_project_key() { | |||
userSession.addPermission(PROVISION_PROJECTS, db.getDefaultOrganization()); | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Malformed key for Project: project%Key. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
expectedException.expectMessage("Malformed key for Project: 'project Key'. It cannot be empty nor contain whitespaces."); | |||
call(CreateRequest.builder() | |||
.setKey("project%Key") | |||
.setKey("project Key") | |||
.setName(DEFAULT_PROJECT_NAME) | |||
.build()); | |||
} |
@@ -30,11 +30,12 @@ public final class ComponentKeys { | |||
public static final int MAX_COMPONENT_KEY_LENGTH = 400; | |||
/* | |||
* Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit | |||
* Must not be blank or empty | |||
*/ | |||
private static final String VALID_PROJECT_KEY_REGEXP = "[\\p{Alnum}\\-_.:]*[\\p{Alpha}\\-_.:]+[\\p{Alnum}\\-_.:]*"; | |||
private static final String VALID_PROJECT_KEY_REGEXP = "[^\\p{javaWhitespace}]+"; | |||
private static final String VALID_PROJECT_KEY_ISSUES_MODE_REGEXP = "[\\p{Alnum}\\-_.:/]*[\\p{Alpha}\\-_.:/]+[\\p{Alnum}\\-_.:/]*"; | |||
/* | |||
* Allowed characters are alphanumeric, '-', '_', '.' and '/' | |||
*/ | |||
@@ -60,18 +61,7 @@ public final class ComponentKeys { | |||
} | |||
/** | |||
* <p>Test if given parameter is valid for a project. Valid format is:</p> | |||
* <ul> | |||
* <li>Allowed characters: | |||
* <ul> | |||
* <li>Uppercase ASCII letters A-Z</li> | |||
* <li>Lowercase ASCII letters a-z</li> | |||
* <li>ASCII digits 0-9</li> | |||
* <li>Punctuation signs dash '-', underscore '_', period '.' and colon ':'</li> | |||
* </ul> | |||
* </li> | |||
* <li>At least one non-digit</li> | |||
* </ul> | |||
* Test if given parameter is valid for a project. A key is valid if it doesn't contain whitespaces. | |||
* | |||
* @return <code>true</code> if <code>keyCandidate</code> can be used for a project | |||
*/ | |||
@@ -85,12 +75,24 @@ public final class ComponentKeys { | |||
* @throws IllegalArgumentException if the format is incorrect | |||
*/ | |||
public static void checkProjectKey(String keyCandidate) { | |||
checkArgument(isValidProjectKey(keyCandidate), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", | |||
keyCandidate); | |||
checkArgument(isValidProjectKey(keyCandidate), "Malformed key for '%s'. %s", keyCandidate, "Project key cannot be empty nor contain whitespaces."); | |||
} | |||
/** | |||
* Same as {@link #isValidProjectKey(String)}, but allows additionally '/'. | |||
* <p>Test if given parameter is valid for a project. Valid format is:</p> | |||
* <ul> | |||
* <li>Allowed characters: | |||
* <ul> | |||
* <li>Uppercase ASCII letters A-Z</li> | |||
* <li>Lowercase ASCII letters a-z</li> | |||
* <li>ASCII digits 0-9</li> | |||
* <li>Punctuation signs dash '-', underscore '_', period '.', colon ':' and slash '/'</li> | |||
* </ul> | |||
* </li> | |||
* <li>At least one non-digit</li> | |||
* </ul> | |||
* | |||
* @return <code>true</code> if <code>keyCandidate</code> can be used for a project in issues mode | |||
*/ | |||
public static boolean isValidProjectKeyIssuesMode(String keyCandidate) { | |||
return keyCandidate.matches(VALID_PROJECT_KEY_ISSUES_MODE_REGEXP); |
@@ -47,13 +47,17 @@ public class ComponentKeysTest { | |||
} | |||
@Test | |||
public void isValidModuleKey() { | |||
assertThat(ComponentKeys.isValidProjectKey("")).isFalse(); | |||
public void isValidProjectKey() { | |||
assertThat(ComponentKeys.isValidProjectKey("abc")).isTrue(); | |||
assertThat(ComponentKeys.isValidProjectKey("0123")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey("ab 12")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey("0123")).isTrue(); | |||
assertThat(ComponentKeys.isValidProjectKey("ab_12")).isTrue(); | |||
assertThat(ComponentKeys.isValidProjectKey("ab/12")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey("ab/12")).isTrue(); | |||
assertThat(ComponentKeys.isValidProjectKey("코드품질")).isTrue(); | |||
assertThat(ComponentKeys.isValidProjectKey("")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey(" ")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey("ab 12")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey(" ab")).isFalse(); | |||
assertThat(ComponentKeys.isValidProjectKey("ab ")).isFalse(); | |||
} | |||
@Test | |||
@@ -79,37 +83,22 @@ public class ComponentKeysTest { | |||
} | |||
@Test | |||
public void checkModuleKey_with_correct_keys() { | |||
public void checkProjectKey_with_correct_keys() { | |||
ComponentKeys.checkProjectKey("abc"); | |||
ComponentKeys.checkProjectKey("a-b_1.:2"); | |||
} | |||
@Test | |||
public void checkModuleKey_fail_if_only_digit() { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Malformed key for '0123'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); | |||
ComponentKeys.checkProjectKey("0123"); | |||
} | |||
@Test | |||
public void checkModuleKey_fail_if_key_is_empty() { | |||
public void checkProjectKey_fail_if_key_is_empty() { | |||
expectedException.expect(IllegalArgumentException.class); | |||
ComponentKeys.checkProjectKey(""); | |||
} | |||
@Test | |||
public void checkModuleKey_fail_if_space() { | |||
public void checkProjectKey_fail_if_space() { | |||
expectedException.expect(IllegalArgumentException.class); | |||
ComponentKeys.checkProjectKey("ab 12"); | |||
} | |||
@Test | |||
public void checkModuleKey_fail_if_special_characters_not_allowed() { | |||
expectedException.expect(IllegalArgumentException.class); | |||
ComponentKeys.checkProjectKey("ab/12"); | |||
} | |||
} |
@@ -117,8 +117,7 @@ public class ProjectReactorValidator { | |||
private static void validateModule(ProjectDefinition moduleDef, List<String> validationMessages) { | |||
if (!ComponentKeys.isValidProjectKey(moduleDef.getKey())) { | |||
validationMessages.add(format("\"%s\" is not a valid project or module key. " | |||
+ "Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", moduleDef.getKey())); | |||
validationMessages.add(format("\"%s\" is not a valid project or module key. It cannot be empty nor contain whitespaces.", moduleDef.getKey())); | |||
} | |||
} | |||
@@ -91,28 +91,14 @@ public class ProjectReactorValidatorTest { | |||
public void allow_slash_issues_mode() { | |||
when(mode.isIssues()).thenReturn(true); | |||
underTest.validate(createProjectReactor("project/key")); | |||
when(mode.isIssues()).thenReturn(false); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("is not a valid project or module key"); | |||
underTest.validate(createProjectReactor("project/key")); | |||
} | |||
@Test | |||
public void fail_with_invalid_key() { | |||
ProjectReactor reactor = createProjectReactor("foo$bar"); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("\"foo$bar\" is not a valid project or module key"); | |||
underTest.validate(reactor); | |||
} | |||
@Test | |||
public void fail_with_backslash_in_key() { | |||
ProjectReactor reactor = createProjectReactor("foo\\bar"); | |||
ProjectReactor reactor = createProjectReactor(" "); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("\"foo\\bar\" is not a valid project or module key"); | |||
thrown.expectMessage("\" \" is not a valid project or module key"); | |||
underTest.validate(reactor); | |||
} | |||
@@ -155,16 +141,6 @@ public class ProjectReactorValidatorTest { | |||
}; | |||
} | |||
@Test | |||
public void fail_with_only_digits() { | |||
ProjectReactor reactor = createProjectReactor("12345"); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("\"12345\" is not a valid project or module key"); | |||
underTest.validate(reactor); | |||
} | |||
@Test | |||
public void fail_when_branch_name_is_specified_but_branch_plugin_not_present() { | |||
ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo"); |