]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7986 Remove property set values when removing property set
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 26 Aug 2016 15:18:45 +0000 (17:18 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 30 Aug 2016 07:30:12 +0000 (09:30 +0200)
server/sonar-server/src/main/java/org/sonar/server/settings/ws/PropertySetExtractor.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/settings/ws/ResetAction.java
server/sonar-server/src/main/java/org/sonar/server/settings/ws/SettingsFinder.java
server/sonar-server/src/main/java/org/sonar/server/settings/ws/SettingsUpdater.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/settings/ws/SettingsWsModule.java
server/sonar-server/src/test/java/org/sonar/server/settings/ws/ResetActionTest.java
server/sonar-server/src/test/java/org/sonar/server/settings/ws/SettingsUpdaterTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/settings/ws/SettingsWsModuleTest.java
sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java

diff --git a/server/sonar-server/src/main/java/org/sonar/server/settings/ws/PropertySetExtractor.java b/server/sonar-server/src/main/java/org/sonar/server/settings/ws/PropertySetExtractor.java
new file mode 100644 (file)
index 0000000..2e27c1d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.settings.ws;
+
+import com.google.common.base.Splitter;
+import java.util.HashSet;
+import java.util.Set;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.db.property.PropertyDto;
+
+public class PropertySetExtractor {
+
+  private static final Splitter COMMA_SPLITTER = Splitter.on(",");
+
+  private PropertySetExtractor() {
+    // Only static stuff
+  }
+
+  public static Set<String> extractPropertySetKeys(PropertyDto propertyDto, PropertyDefinition definition) {
+    Set<String> propertySetKeys = new HashSet<>();
+    definition.fields()
+      .forEach(field -> COMMA_SPLITTER.splitToList(propertyDto.getValue())
+        .forEach(setId -> propertySetKeys.add(generatePropertySetKey(propertyDto.getKey(), setId, field.key()))));
+    return propertySetKeys;
+  }
+
+  private static String generatePropertySetKey(String propertyBaseKey, String id, String fieldKey) {
+    return propertyBaseKey + "." + id + "." + fieldKey;
+  }
+}
index 6442e6c27bd10600143a2fb9c737e8177f897826..3c24e053d7b7e2b29e576ec70319edbb0c3aa6be 100644 (file)
@@ -44,12 +44,14 @@ import static org.sonarqube.ws.client.setting.SettingsWsParameters.PARAM_KEY;
 public class ResetAction implements SettingsWsAction {
 
   private final DbClient dbClient;
-  private final UserSession userSession;
   private final ComponentFinder componentFinder;
+  private final SettingsUpdater settingsUpdater;
+  private final UserSession userSession;
   private final PropertyDefinitions definitions;
 
-  public ResetAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions definitions) {
+  public ResetAction(DbClient dbClient, ComponentFinder componentFinder, SettingsUpdater settingsUpdater, UserSession userSession, PropertyDefinitions definitions) {
     this.dbClient = dbClient;
+    this.settingsUpdater = settingsUpdater;
     this.userSession = userSession;
     this.componentFinder = componentFinder;
     this.definitions = definitions;
@@ -87,9 +89,9 @@ public class ResetAction implements SettingsWsAction {
       PropertyDefinition definition = definitions.get(resetRequest.getKey());
       String key = definition != null ? definition.key() : resetRequest.getKey();
       if (component.isPresent()) {
-        dbClient.propertiesDao().deleteProjectProperty(key, component.get().getId(), dbSession);
+        settingsUpdater.deleteComponentSetting(dbSession, key, component.get());
       } else {
-        dbClient.propertiesDao().deleteGlobalProperty(key, dbSession);
+        settingsUpdater.deleteGlobalSetting(dbSession, key);
       }
       dbSession.commit();
       response.noContent();
index e2ed8ffd35decfe4a5d17e1eff43af6c07426999..11c5011310fea5b31ecab9147296ebf74f62f9b1 100644 (file)
@@ -24,7 +24,6 @@ import com.google.common.base.Splitter;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Ordering;
 import com.google.common.collect.TreeMultimap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -38,11 +37,11 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.property.PropertyDto;
 
 import static org.sonar.api.PropertyType.PROPERTY_SET;
+import static org.sonar.server.settings.ws.PropertySetExtractor.extractPropertySetKeys;
 
 public class SettingsFinder {
 
   private static final Splitter DOT_SPLITTER = Splitter.on(".").omitEmptyStrings();
-  private static final Splitter COMMA_SPLITTER = Splitter.on(",");
 
   private final DbClient dbClient;
   private final PropertyDefinitions definitions;
@@ -83,18 +82,11 @@ public class SettingsFinder {
   }
 
   private Set<String> getPropertySetKeys(List<PropertyDto> properties) {
-    Set<String> propertySetKeys = new HashSet<>();
-    properties.stream()
+    return properties.stream()
       .filter(propertyDto -> definitions.get(propertyDto.getKey()) != null)
       .filter(propertyDto -> definitions.get(propertyDto.getKey()).type().equals(PROPERTY_SET))
-      .forEach(propertyDto -> definitions.get(propertyDto.getKey()).fields()
-        .forEach(field -> COMMA_SPLITTER.splitToList(propertyDto.getValue())
-          .forEach(setId -> propertySetKeys.add(generatePropertySetKey(propertyDto.getKey(), setId, field.key())))));
-    return propertySetKeys;
-  }
-
-  private static String generatePropertySetKey(String propertyBaseKey, String id, String fieldKey) {
-    return propertyBaseKey + "." + id + "." + fieldKey;
+      .flatMap(propertyDto -> extractPropertySetKeys(propertyDto, definitions.get(propertyDto.getKey())).stream())
+      .collect(Collectors.toSet());
   }
 
   private static List<PropertyDto> getPropertySets(String propertyKey, List<PropertyDto> propertySets, @Nullable Long componentId) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/settings/ws/SettingsUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/settings/ws/SettingsUpdater.java
new file mode 100644 (file)
index 0000000..270913f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.settings.ws;
+
+import java.util.Optional;
+import java.util.Set;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.property.PropertyDto;
+
+import static org.sonar.server.settings.ws.PropertySetExtractor.extractPropertySetKeys;
+
+public class SettingsUpdater {
+
+  private final DbClient dbClient;
+  private final PropertyDefinitions definitions;
+
+  public SettingsUpdater(DbClient dbClient, PropertyDefinitions definitions) {
+    this.dbClient = dbClient;
+    this.definitions = definitions;
+  }
+
+  public void deleteGlobalSetting(DbSession dbSession, String propertyKey) {
+    delete(dbSession, propertyKey, Optional.empty());
+  }
+
+  public void deleteComponentSetting(DbSession dbSession, String propertyKey, ComponentDto componentDto) {
+    delete(dbSession, propertyKey, Optional.of(componentDto));
+  }
+
+  private void delete(DbSession dbSession, String propertyKey, Optional<ComponentDto> componentDto) {
+    PropertyDefinition definition = definitions.get(propertyKey);
+    if (definition == null || !definition.type().equals(PropertyType.PROPERTY_SET)) {
+      deleteSetting(dbSession, propertyKey, componentDto);
+    } else {
+      deletePropertySet(dbSession, propertyKey, definition, componentDto);
+    }
+  }
+
+  private void deleteSetting(DbSession dbSession, String propertyKey, Optional<ComponentDto> componentDto) {
+    if (componentDto.isPresent()) {
+      dbClient.propertiesDao().deleteProjectProperty(propertyKey, componentDto.get().getId(), dbSession);
+    } else {
+      dbClient.propertiesDao().deleteGlobalProperty(propertyKey, dbSession);
+    }
+  }
+
+  private void deletePropertySet(DbSession dbSession, String propertyKey, PropertyDefinition definition, Optional<ComponentDto> componentDto) {
+    Optional<PropertyDto> propertyDto = selectPropertyDto(dbSession, propertyKey, componentDto);
+    if (!propertyDto.isPresent()) {
+      // Setting doesn't exist, nothing to do
+      return;
+    }
+    Set<String> propertySetKeys = extractPropertySetKeys(propertyDto.get(), definition);
+    for (String key : propertySetKeys) {
+      deleteSetting(dbSession, key, componentDto);
+    }
+    deleteSetting(dbSession, propertyKey, componentDto);
+  }
+
+  private Optional<PropertyDto> selectPropertyDto(DbSession dbSession, String propertyKey, Optional<ComponentDto> componentDto) {
+    if (componentDto.isPresent()) {
+      return Optional.ofNullable(dbClient.propertiesDao().selectProjectProperty(dbSession, componentDto.get().getId(), propertyKey));
+    } else {
+      return Optional.ofNullable(dbClient.propertiesDao().selectGlobalProperty(dbSession, propertyKey));
+    }
+  }
+
+}
index 9624d697e5b6a5c2e02715dc86570c23de8b3e91..5a1caa02652cfc1d84e6f37266d3468b61e89c41 100644 (file)
@@ -31,6 +31,7 @@ public class SettingsWsModule extends Module {
       ListDefinitionsAction.class,
       ValuesAction.class,
       SettingsFinder.class,
-      ResetAction.class);
+      ResetAction.class,
+      SettingsUpdater.class);
   }
 }
index 0b37723dd94350caff97ec5a72b0f78d12d6283e..1663cee0eaf7e3d3203256b19b503bd8b2844488 100644 (file)
@@ -39,6 +39,7 @@ import org.sonar.db.property.PropertyQuery;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserTesting;
 import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
@@ -48,6 +49,8 @@ import org.sonarqube.ws.MediaTypes;
 import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.db.component.ComponentTesting.newProjectDto;
 import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto;
@@ -71,10 +74,11 @@ public class ResetActionTest {
   DbSession dbSession = db.getSession();
   ComponentFinder componentFinder = new ComponentFinder(dbClient);
   PropertyDefinitions definitions = new PropertyDefinitions();
+  SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
 
   ComponentDto project;
 
-  ResetAction underTest = new ResetAction(dbClient, componentFinder, userSession, definitions);
+  ResetAction underTest = new ResetAction(dbClient, componentFinder, settingsUpdater, userSession, definitions);
   WsActionTester ws = new WsActionTester(underTest);
 
   @Before
@@ -93,7 +97,7 @@ public class ResetActionTest {
 
   @Test
   public void remove_component_setting() throws Exception {
-    setUserAsSystemAdmin();
+    setUserAsProjectAdmin();
     propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("value"));
 
     executeRequestOnProjectSetting("foo");
@@ -114,7 +118,7 @@ public class ResetActionTest {
 
   @Test
   public void ignore_global_setting_when_removing_project_setting() throws Exception {
-    setUserAsSystemAdmin();
+    setUserAsProjectAdmin();
     propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one"));
     propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("value"));
 
@@ -136,7 +140,7 @@ public class ResetActionTest {
 
   @Test
   public void ignore_user_setting_when_removing_project_setting() throws Exception {
-    setUserAsSystemAdmin();
+    setUserAsProjectAdmin();
     UserDto user = dbClient.userDao().insert(dbSession, UserTesting.newUserDto());
     propertyDb.insertProperties(newUserPropertyDto("foo", "one", user));
 
@@ -182,6 +186,26 @@ public class ResetActionTest {
     assertThat(action.params()).hasSize(3);
   }
 
+  @Test
+  public void fail_when_not_system_admin() throws Exception {
+    userSession.login("not-admin").setGlobalPermissions(DASHBOARD_SHARING);
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+
+    expectedException.expect(ForbiddenException.class);
+
+    executeRequestOnGlobalSetting("foo");
+  }
+
+  @Test
+  public void fail_when_not_project_admin() throws Exception {
+    userSession.login("project-admin").addProjectUuidPermissions(USER, project.uuid());
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+
+    expectedException.expect(ForbiddenException.class);
+
+    executeRequestOnComponentSetting("foo", project);
+  }
+
   private void executeRequestOnGlobalSetting(String key) {
     executeRequest(key, null, null);
   }
@@ -216,11 +240,11 @@ public class ResetActionTest {
   }
 
   private void assertGlobalPropertyDoesNotExist(String key) {
-    assertThat(dbClient.propertiesDao().selectGlobalProperty(key)).isNull();
+    assertThat(dbClient.propertiesDao().selectGlobalProperty(dbSession, key)).isNull();
   }
 
   private void assertGlobalPropertyExists(String key) {
-    assertThat(dbClient.propertiesDao().selectGlobalProperty(key)).isNotNull();
+    assertThat(dbClient.propertiesDao().selectGlobalProperty(dbSession, key)).isNotNull();
   }
 
   private void assertProjectPropertyDoesNotExist(String key) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/settings/ws/SettingsUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/settings/ws/SettingsUpdaterTest.java
new file mode 100644 (file)
index 0000000..7ac5c0f
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.settings.ws;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.PropertyFieldDefinition;
+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.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.property.PropertyDbTester;
+import org.sonar.db.property.PropertyQuery;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserTesting;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto;
+import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;
+import static org.sonar.db.property.PropertyTesting.newUserPropertyDto;
+
+public class SettingsUpdaterTest {
+
+  @Rule
+  public DbTester db = DbTester.create(System2.INSTANCE);
+
+  DbClient dbClient = db.getDbClient();
+  DbSession dbSession = db.getSession();
+
+  PropertyDbTester propertyDb = new PropertyDbTester(db);
+  ComponentDbTester componentDb = new ComponentDbTester(db);
+
+  PropertyDefinitions definitions = new PropertyDefinitions();
+  ComponentDto project;
+
+  SettingsUpdater underTest= new SettingsUpdater(dbClient, definitions);
+
+  @Before
+  public void setUp() throws Exception {
+    project = componentDb.insertComponent(newProjectDto());
+  }
+
+  @Test
+  public void delete_global_setting() throws Exception {
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one"));
+    propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("value"));
+
+    underTest.deleteGlobalSetting(dbSession, "foo");
+
+    assertGlobalPropertyDoesNotExist("foo");
+    assertProjectPropertyExists("foo");
+  }
+
+  @Test
+  public void delete_component_setting() throws Exception {
+    definitions.addComponent(PropertyDefinition.builder("foo").build());
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one"));
+    propertyDb.insertProperties(newComponentPropertyDto(project).setKey("foo").setValue("value"));
+
+    underTest.deleteComponentSetting(dbSession, "foo", project);
+
+    assertProjectPropertyDoesNotExist("foo");
+    assertGlobalPropertyExists("foo");
+  }
+
+  @Test
+  public void does_not_fail_when_deleting_unknown_setting() throws Exception {
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one"));
+
+    underTest.deleteGlobalSetting(dbSession, "unknown");
+
+    assertGlobalPropertyExists("foo");
+  }
+
+  @Test
+  public void does_not_delete_user_settings() throws Exception {
+    UserDto user = dbClient.userDao().insert(dbSession, UserTesting.newUserDto());
+    propertyDb.insertProperties(newUserPropertyDto("foo", "one", user));
+    propertyDb.insertProperties(newGlobalPropertyDto().setKey("foo").setValue("one"));
+
+    underTest.deleteGlobalSetting(dbSession, "foo");
+
+    assertUserPropertyExists("foo", user);
+  }
+
+  @Test
+  public void delete_global_property_set() throws Exception {
+    definitions.addComponent(PropertyDefinition
+      .builder("foo")
+      .type(PropertyType.PROPERTY_SET)
+      .fields(asList(
+        PropertyFieldDefinition.build("key").name("Key").build(),
+        PropertyFieldDefinition.build("size").name("Size").build()))
+      .build());
+    propertyDb.insertProperties(
+      newGlobalPropertyDto().setKey("foo").setValue("1,2"),
+      newGlobalPropertyDto().setKey("foo.1.key").setValue("key1"),
+      newGlobalPropertyDto().setKey("foo.1.size").setValue("size1"),
+      newGlobalPropertyDto().setKey("foo.2.key").setValue("key2"));
+
+    underTest.deleteGlobalSetting(dbSession, "foo");
+
+    assertGlobalPropertyDoesNotExist("foo");
+    assertGlobalPropertyDoesNotExist("foo.1.key");
+    assertGlobalPropertyDoesNotExist("foo.1.size");
+    assertGlobalPropertyDoesNotExist("foo.2.key");
+  }
+
+  @Test
+  public void delete_component_property_set() throws Exception {
+    definitions.addComponent(PropertyDefinition
+      .builder("foo")
+      .type(PropertyType.PROPERTY_SET)
+      .fields(asList(
+        PropertyFieldDefinition.build("key").name("Key").build(),
+        PropertyFieldDefinition.build("size").name("Size").build()))
+      .build());
+    propertyDb.insertProperties(
+      newComponentPropertyDto(project).setKey("foo").setValue("1,2"),
+      newComponentPropertyDto(project).setKey("foo.1.key").setValue("key1"),
+      newComponentPropertyDto(project).setKey("foo.1.size").setValue("size1"),
+      newComponentPropertyDto(project).setKey("foo.2.key").setValue("key2"));
+
+    underTest.deleteComponentSetting(dbSession, "foo", project);
+
+    assertProjectPropertyDoesNotExist("foo");
+    assertProjectPropertyDoesNotExist("foo.1.key");
+    assertProjectPropertyDoesNotExist("foo.1.size");
+    assertProjectPropertyDoesNotExist("foo.2.key");
+  }
+
+  @Test
+  public void does_not_fail_when_deleting_unknown_property_set() throws Exception {
+    definitions.addComponent(PropertyDefinition
+      .builder("foo")
+      .type(PropertyType.PROPERTY_SET)
+      .fields(asList(
+        PropertyFieldDefinition.build("key").name("Key").build(),
+        PropertyFieldDefinition.build("size").name("Size").build()))
+      .build());
+    propertyDb.insertProperties(
+      newComponentPropertyDto(project).setKey("other").setValue("1,2"),
+      newComponentPropertyDto(project).setKey("other.1.key").setValue("key1"));
+
+    underTest.deleteComponentSetting(dbSession, "foo", project);
+
+    assertProjectPropertyExists("other");
+  }
+
+  private void assertGlobalPropertyDoesNotExist(String key) {
+    assertThat(dbClient.propertiesDao().selectGlobalProperty(dbSession, key)).isNull();
+  }
+
+  private void assertGlobalPropertyExists(String key) {
+    assertThat(dbClient.propertiesDao().selectGlobalProperty(dbSession, key)).isNotNull();
+  }
+
+  private void assertProjectPropertyDoesNotExist(String key) {
+    assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(project.getId()).setKey(key).build(), dbSession)).isEmpty();
+  }
+
+  private void assertProjectPropertyExists(String key) {
+    assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setComponentId(project.getId()).setKey(key).build(), dbSession)).isNotEmpty();
+  }
+
+  private void assertUserPropertyExists(String key, UserDto user) {
+    assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
+        .setKey(key)
+        .setUserId(user.getId().intValue())
+        .build(),
+      dbSession)).isNotEmpty();
+  }
+}
index f476c5db1b10efe64a669ca540523cb9453f0f41..18a54cfd494ffe5a9b98b82fb189c0e3852bbe53 100644 (file)
@@ -29,6 +29,6 @@ public class SettingsWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new SettingsWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(7 + 2);
+    assertThat(container.size()).isEqualTo(8 + 2);
   }
 }
index 38683018c9107783c1aee6d9354c1d609da6f331..cba42d90e9f31af2f4c7739d25bbfb631af2b1e8 100644 (file)
@@ -152,14 +152,18 @@ public class PropertiesDao implements Dao {
   @CheckForNull
   public PropertyDto selectProjectProperty(long resourceId, String propertyKey) {
     DbSession session = mybatis.openSession(false);
-    PropertiesMapper mapper = session.getMapper(PropertiesMapper.class);
     try {
-      return mapper.selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(resourceId));
+      return selectProjectProperty(session, resourceId, propertyKey);
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
+  @CheckForNull
+  public PropertyDto selectProjectProperty(DbSession dbSession, long resourceId, String propertyKey) {
+    return dbSession.getMapper(PropertiesMapper.class).selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(resourceId));
+  }
+
   public List<PropertyDto> selectByQuery(PropertyQuery query, DbSession session) {
     return session.getMapper(PropertiesMapper.class).selectByQuery(query);
   }