diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-03-18 14:58:27 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-03-18 14:58:53 +0100 |
commit | d8615a4edd4f958109de1b8dcd3caebb8958a55e (patch) | |
tree | 8e8fcd02fa92cb0b70752b93334c0a5c9277fc3d /sonar-server/src | |
parent | b447bcd53e30432c43b9808d10e576cc95764182 (diff) | |
download | sonarqube-d8615a4edd4f958109de1b8dcd3caebb8958a55e.tar.gz sonarqube-d8615a4edd4f958109de1b8dcd3caebb8958a55e.zip |
SONAR-5056 Add create profile
Diffstat (limited to 'sonar-server/src')
3 files changed, 166 insertions, 29 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelService.java b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelService.java index a5a32807add..4d314d96d5a 100644 --- a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelService.java +++ b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelService.java @@ -22,13 +22,19 @@ package org.sonar.server.debt; import com.google.common.base.Function; import com.google.common.collect.Iterables; +import org.apache.ibatis.session.SqlSession; import org.sonar.api.server.debt.DebtCharacteristic; import org.sonar.api.server.debt.DebtModel; import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; +import org.sonar.core.persistence.MyBatis; import org.sonar.core.technicaldebt.db.CharacteristicDao; import org.sonar.core.technicaldebt.db.CharacteristicDto; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.util.Validation; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import java.util.Collection; import java.util.List; @@ -37,12 +43,15 @@ import static com.google.common.collect.Lists.newArrayList; /** * Used through ruby code <pre>Internal.debt</pre> + * Also used by SQALE plugin. */ public class DebtModelService implements DebtModel { + private final MyBatis mybatis; private final CharacteristicDao dao; - public DebtModelService(CharacteristicDao dao) { + public DebtModelService(MyBatis mybatis, CharacteristicDao dao) { + this.mybatis = mybatis; this.dao = dao; } @@ -60,6 +69,49 @@ public class DebtModelService implements DebtModel { return dto != null ? toCharacteristic(dto) : null; } + public DebtCharacteristic createCharacteristic(String name, @Nullable Integer parentId) { + SqlSession session = mybatis.openSession(); + try { + checkNotAlreadyExists(name, session); + + CharacteristicDto newCharacteristic = new CharacteristicDto() + .setKey(name.toUpperCase().replace(" ", "_")) + .setName(name) + .setEnabled(true); + + // New sub characteristic + if (parentId != null) { + CharacteristicDto parent = findCharacteristic(parentId); + if (parent.getParentId() != null) { + throw new BadRequestException("A sub characteristic can not have a sub characteristic as parent."); + } + newCharacteristic.setParentId(parent.getId()); + } else { + // New root characteristic + newCharacteristic.setOrder(dao.selectMaxCharacteristicOrder(session)+1); + } + dao.insert(newCharacteristic, session); + session.commit(); + return toCharacteristic(newCharacteristic); + } finally { + MyBatis.closeQuietly(session); + } + } + + private CharacteristicDto findCharacteristic(Integer id){ + CharacteristicDto dto = dao.selectById(id); + if (dto == null) { + throw new NotFoundException(String.format("Characteristic with id %s does not exists.", id)); + } + return dto; + } + + private void checkNotAlreadyExists(String name, SqlSession session) { + if (dao.selectByName(name, session) != null) { + throw BadRequestException.ofL10n(Validation.IS_ALREADY_USED_MESSAGE, name); + } + } + private static List<DebtCharacteristic> toCharacteristics(Collection<CharacteristicDto> dtos) { return newArrayList(Iterables.transform(dtos, new Function<CharacteristicDto, DebtCharacteristic>() { @Override diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/characteristic.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/characteristic.rb index e04b5154720..42708225ed8 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/characteristic.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/characteristic.rb @@ -30,10 +30,9 @@ class Characteristic < ActiveRecord::Base MINUTE = "mn" belongs_to :parent, :class_name => 'Characteristic', :foreign_key => 'parent_id' - belongs_to :rule - validates_uniqueness_of :name, :scope => [:enabled], :case_sensitive => false, :if => Proc.new { |c| c.rule_id.nil? && c.enabled } - validates_length_of :name, :in => 1..NAME_MAX_SIZE, :allow_blank => false, :if => Proc.new { |c| c.rule_id.nil? } + validates_uniqueness_of :name, :scope => [:enabled], :case_sensitive => false, :if => Proc.new { |c| c.enabled } + validates_length_of :name, :in => 1..NAME_MAX_SIZE, :allow_blank => false def root? parent_id.nil? @@ -48,11 +47,7 @@ class Characteristic < ActiveRecord::Base end def name(rule_name_if_empty=false) - result=read_attribute(:name) - if (result.nil? && rule_name_if_empty && rule_id) - result=rule.name - end - result + read_attribute(:name) end end diff --git a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelServiceTest.java b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelServiceTest.java index 8a59e05b387..3277e46cf90 100644 --- a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelServiceTest.java @@ -19,17 +19,26 @@ */ package org.sonar.server.debt; +import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; import org.sonar.api.server.debt.DebtCharacteristic; +import org.sonar.core.persistence.MyBatis; import org.sonar.core.technicaldebt.db.CharacteristicDao; import org.sonar.core.technicaldebt.db.CharacteristicDto; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.NotFoundException; import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -38,51 +47,132 @@ public class DebtModelServiceTest { @Mock CharacteristicDao dao; + @Mock + MyBatis mybatis; + + @Mock + SqlSession session; + DebtModelService service; + CharacteristicDto rootCharacteristicDto = new CharacteristicDto() + .setId(1) + .setKey("MEMORY_EFFICIENCY") + .setName("Memory use") + .setOrder(1); + + CharacteristicDto characteristicDto = new CharacteristicDto() + .setId(2) + .setKey("EFFICIENCY") + .setName("Efficiency") + .setParentId(1); + + int currentId; + @Before public void setUp() throws Exception { - service = new DebtModelService(dao); + currentId = 10; + + // Associate an id when inserting an object to simulate the db id generator + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + CharacteristicDto dto = (CharacteristicDto) args[0]; + dto.setId(++currentId); + return null; + } + }).when(dao).insert(any(CharacteristicDto.class), any(SqlSession.class)); + + when(mybatis.openSession()).thenReturn(session); + service = new DebtModelService(mybatis, dao); } @Test public void find_root_characteristics() { - CharacteristicDto dto = new CharacteristicDto() - .setId(1) - .setKey("MEMORY_EFFICIENCY") - .setName("Memory use"); - when(dao.selectEnabledRootCharacteristics()).thenReturn(newArrayList(dto)); + when(dao.selectEnabledRootCharacteristics()).thenReturn(newArrayList(rootCharacteristicDto)); assertThat(service.rootCharacteristics()).hasSize(1); } @Test public void find_characteristics() { - CharacteristicDto dto = new CharacteristicDto() - .setId(1) - .setKey("MEMORY_EFFICIENCY") - .setName("Memory use"); - when(dao.selectEnabledCharacteristics()).thenReturn(newArrayList(dto)); + when(dao.selectEnabledCharacteristics()).thenReturn(newArrayList(rootCharacteristicDto)); assertThat(service.characteristics()).hasSize(1); } @Test public void find_characteristic_by_id() { - CharacteristicDto dto = new CharacteristicDto() - .setId(1) - .setKey("MEMORY_EFFICIENCY") - .setName("Memory use") - .setParentId(2) - .setOrder(1); - when(dao.selectById(1)).thenReturn(dto); + when(dao.selectById(1)).thenReturn(rootCharacteristicDto); DebtCharacteristic characteristic = service.characteristicById(1); assertThat(characteristic.id()).isEqualTo(1); assertThat(characteristic.key()).isEqualTo("MEMORY_EFFICIENCY"); assertThat(characteristic.name()).isEqualTo("Memory use"); - assertThat(characteristic.parentId()).isEqualTo(2); assertThat(characteristic.order()).isEqualTo(1); + assertThat(characteristic.parentId()).isNull(); + + assertThat(service.characteristicById(111)).isNull(); + } + + @Test + public void create_sub_characteristic() { + when(dao.selectById(1)).thenReturn(rootCharacteristicDto); + + DebtCharacteristic result = service.createCharacteristic("Compilation name", 1); + + assertThat(result.id()).isEqualTo(currentId); + assertThat(result.key()).isEqualTo("COMPILATION_NAME"); + assertThat(result.name()).isEqualTo("Compilation name"); + assertThat(result.parentId()).isEqualTo(1); + } + + @Test + public void fail_to_create_sub_characteristic_when_parent_id_is_not_a_root_characteristic() { + when(dao.selectById(1)).thenReturn(characteristicDto); + + try { + service.createCharacteristic("Compilation", 1); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("A sub characteristic can not have a sub characteristic as parent."); + } + } + + @Test + public void fail_to_create_sub_characteristic_when_parent_does_not_exists() { + when(dao.selectById(1)).thenReturn(null); + + try { + service.createCharacteristic("Compilation", 1); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(NotFoundException.class).hasMessage("Characteristic with id 1 does not exists."); + } + } + + @Test + public void fail_to_create_sub_characteristic_when_name_already_used() { + when(dao.selectByName("Compilation", session)).thenReturn(new CharacteristicDto()); + when(dao.selectById(1)).thenReturn(rootCharacteristicDto); + + try { + service.createCharacteristic("Compilation", 1); + fail(); + } catch (BadRequestException e) { + assertThat(e.l10nKey()).isEqualTo("errors.is_already_used"); + assertThat(e.l10nParams().iterator().next()).isEqualTo("Compilation"); + } + } + + @Test + public void create_characteristic() { + when(dao.selectMaxCharacteristicOrder(session)).thenReturn(1); + + DebtCharacteristic result = service.createCharacteristic("Portability", null); - assertThat(service.characteristicById(10)).isNull(); + assertThat(result.id()).isEqualTo(currentId); + assertThat(result.key()).isEqualTo("PORTABILITY"); + assertThat(result.name()).isEqualTo("Portability"); + assertThat(result.order()).isEqualTo(2); } } |