From b5da9d55d9881f33fcc2f63490817289cc1f64ec Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Tue, 20 Sep 2016 17:11:09 +0200 Subject: [PATCH] SONAR-8095 add OrganizationDao --- .../ComputeEngineContainerImplTest.java | 2 +- .../src/main/java/org/sonar/db/DaoModule.java | 5 +- .../src/main/java/org/sonar/db/DbClient.java | 7 + .../src/main/java/org/sonar/db/MyBatis.java | 4 + .../db/organization/OrganizationDao.java | 48 +++++ .../db/organization/OrganizationDto.java | 126 ++++++++++++ .../db/organization/OrganizationMapper.java | 33 +++ .../sonar/db/organization/package-info.java | 24 +++ .../db/organization/OrganizationMapper.xml | 56 +++++ .../test/java/org/sonar/db/DaoModuleTest.java | 2 +- .../db/organization/OrganizationDaoTest.java | 192 ++++++++++++++++++ 11 files changed, 495 insertions(+), 4 deletions(-) create mode 100644 sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java create mode 100644 sonar-db/src/main/java/org/sonar/db/organization/OrganizationDto.java create mode 100644 sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java create mode 100644 sonar-db/src/main/java/org/sonar/db/organization/package-info.java create mode 100644 sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml create mode 100644 sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java index 3270c9ce209..b027d5e4cae 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java @@ -106,7 +106,7 @@ public class ComputeEngineContainerImplTest { assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize( COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION + 24 // level 1 - + 50 // content of DaoModule + + 51 // content of DaoModule + 2 // content of EsSearchModule + 61 // content of CorePropertyDefinitions + 1 // content of CePropertyDefinitions diff --git a/sonar-db/src/main/java/org/sonar/db/DaoModule.java b/sonar-db/src/main/java/org/sonar/db/DaoModule.java index fda49f5534c..f6c2c8a8696 100644 --- a/sonar-db/src/main/java/org/sonar/db/DaoModule.java +++ b/sonar-db/src/main/java/org/sonar/db/DaoModule.java @@ -49,6 +49,7 @@ import org.sonar.db.measure.MeasureFilterFavouriteDao; import org.sonar.db.measure.custom.CustomMeasureDao; import org.sonar.db.metric.MetricDao; import org.sonar.db.notification.NotificationQueueDao; +import org.sonar.db.organization.OrganizationDao; import org.sonar.db.permission.PermissionDao; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDao; import org.sonar.db.permission.template.PermissionTemplateDao; @@ -101,6 +102,7 @@ public class DaoModule extends Module { MeasureFilterFavouriteDao.class, MetricDao.class, NotificationQueueDao.class, + OrganizationDao.class, PermissionDao.class, PermissionTemplateDao.class, PermissionTemplateCharacteristicDao.class, @@ -124,8 +126,7 @@ public class DaoModule extends Module { UserGroupDao.class, UserTokenDao.class, WidgetDao.class, - WidgetPropertyDao.class - ).build(); + WidgetPropertyDao.class).build(); @Override protected void configureModule() { diff --git a/sonar-db/src/main/java/org/sonar/db/DbClient.java b/sonar-db/src/main/java/org/sonar/db/DbClient.java index 519d6f140d6..17161835822 100644 --- a/sonar-db/src/main/java/org/sonar/db/DbClient.java +++ b/sonar-db/src/main/java/org/sonar/db/DbClient.java @@ -49,6 +49,7 @@ import org.sonar.db.measure.MeasureFilterFavouriteDao; import org.sonar.db.measure.custom.CustomMeasureDao; import org.sonar.db.metric.MetricDao; import org.sonar.db.notification.NotificationQueueDao; +import org.sonar.db.organization.OrganizationDao; import org.sonar.db.permission.PermissionDao; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDao; import org.sonar.db.permission.template.PermissionTemplateDao; @@ -77,6 +78,7 @@ public class DbClient { private final Database database; private final MyBatis myBatis; + private final OrganizationDao organizationDao; private final QualityProfileDao qualityProfileDao; private final LoadedTemplateDao loadedTemplateDao; private final PropertiesDao propertiesDao; @@ -136,6 +138,7 @@ public class DbClient { for (Dao dao : daos) { map.put(dao.getClass(), dao); } + organizationDao = getDao(map, OrganizationDao.class); qualityProfileDao = getDao(map, QualityProfileDao.class); loadedTemplateDao = getDao(map, LoadedTemplateDao.class); propertiesDao = getDao(map, PropertiesDao.class); @@ -200,6 +203,10 @@ public class DbClient { return database; } + public OrganizationDao organizationDao() { + return organizationDao; + } + public IssueDao issueDao() { return issueDao; } diff --git a/sonar-db/src/main/java/org/sonar/db/MyBatis.java b/sonar-db/src/main/java/org/sonar/db/MyBatis.java index b0e67be5e90..c82eb692a78 100644 --- a/sonar-db/src/main/java/org/sonar/db/MyBatis.java +++ b/sonar-db/src/main/java/org/sonar/db/MyBatis.java @@ -82,6 +82,8 @@ import org.sonar.db.measure.custom.CustomMeasureMapper; import org.sonar.db.metric.MetricMapper; import org.sonar.db.notification.NotificationQueueDto; import org.sonar.db.notification.NotificationQueueMapper; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.organization.OrganizationMapper; import org.sonar.db.permission.GroupWithPermissionDto; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; @@ -190,6 +192,7 @@ public class MyBatis { confBuilder.loadAlias("MeasureFilter", MeasureFilterDto.class); confBuilder.loadAlias("Measure", MeasureDto.class); confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class); + confBuilder.loadAlias("Organization", OrganizationDto.class); confBuilder.loadAlias("PermissionTemplateCharacteristic", PermissionTemplateCharacteristicDto.class); confBuilder.loadAlias("PermissionTemplateGroup", PermissionTemplateGroupDto.class); confBuilder.loadAlias("PermissionTemplate", PermissionTemplateDto.class); @@ -258,6 +261,7 @@ public class MyBatis { Migration50Mapper.class, Migration53Mapper.class, NotificationQueueMapper.class, + OrganizationMapper.class, PermissionTemplateCharacteristicMapper.class, PermissionTemplateMapper.class, ProjectQgateAssociationMapper.class, diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java new file mode 100644 index 00000000000..8a25287d351 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java @@ -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.db.organization; + +import java.util.Optional; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; + +import static java.util.Objects.requireNonNull; + +public class OrganizationDao implements Dao { + + public void insert(DbSession dbSession, OrganizationDto organization) { + requireNonNull(organization, "OrganizationDto can't be null"); + getMapper(dbSession).insert(organization); + } + + public Optional selectByUuid(DbSession dbSession, String uuid) { + requireNonNull(uuid, "uuid can't be null"); + return Optional.ofNullable(getMapper(dbSession).selectByUuid(uuid)); + } + + public Optional selectByKey(DbSession dbSession, String key) { + requireNonNull(key, "key can't be null"); + return Optional.ofNullable(getMapper(dbSession).selectByKey(key)); + } + + private static OrganizationMapper getMapper(DbSession dbSession) { + return dbSession.getMapper(OrganizationMapper.class); + } +} diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDto.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDto.java new file mode 100644 index 00000000000..095f40e7ef2 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDto.java @@ -0,0 +1,126 @@ +/* + * 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.db.organization; + +import javax.annotation.Nullable; + +public class OrganizationDto { + /** Technical unique identifier, can't be null */ + private String uuid; + /** Functional unique identifier, can't be null */ + private String key; + /** Name, can't be null */ + private String name; + /** description can be null */ + private String description; + /** url can be null */ + private String url; + /** avatar url can be null */ + private String avatarUrl; + private long createdAt; + private long updatedAt; + + public String getUuid() { + return uuid; + } + + public OrganizationDto setUuid(String uuid) { + this.uuid = uuid; + return this; + } + + public String getKey() { + return key; + } + + public OrganizationDto setKey(String key) { + this.key = key; + return this; + } + + public String getName() { + return name; + } + + public OrganizationDto setName(String name) { + this.name = name; + return this; + } + + public long getCreatedAt() { + return createdAt; + } + + public OrganizationDto setCreatedAt(long createdAt) { + this.createdAt = createdAt; + return this; + } + + public long getUpdatedAt() { + return updatedAt; + } + + public OrganizationDto setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + return this; + } + + public String getDescription() { + return description; + } + + public OrganizationDto setDescription(@Nullable String description) { + this.description = description; + return this; + } + + public String getUrl() { + return url; + } + + public OrganizationDto setUrl(@Nullable String url) { + this.url = url; + return this; + } + + public String getAvatarUrl() { + return avatarUrl; + } + + public OrganizationDto setAvatarUrl(@Nullable String avatarUrl) { + this.avatarUrl = avatarUrl; + return this; + } + + @Override + public String toString() { + return "OrganizationDto{" + + "uuid='" + uuid + '\'' + + ", key='" + key + '\'' + + ", name='" + name + '\'' + + ", description='" + description + '\'' + + ", url='" + url + '\'' + + ", avatarUrl='" + avatarUrl + '\'' + + ", createdAt=" + createdAt + + ", updatedAt=" + updatedAt + + '}'; + } + +} diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java new file mode 100644 index 00000000000..bcf515eae94 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java @@ -0,0 +1,33 @@ +/* + * 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.db.organization; + +import javax.annotation.CheckForNull; +import org.apache.ibatis.annotations.Param; + +public interface OrganizationMapper { + void insert(@Param("organization") OrganizationDto organization); + + @CheckForNull + OrganizationDto selectByKey(@Param("key") String key); + + @CheckForNull + OrganizationDto selectByUuid(@Param("uuid") String uuid); +} diff --git a/sonar-db/src/main/java/org/sonar/db/organization/package-info.java b/sonar-db/src/main/java/org/sonar/db/organization/package-info.java new file mode 100644 index 00000000000..14ab773fbe9 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/organization/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.db.organization; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml b/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml new file mode 100644 index 00000000000..259d5761240 --- /dev/null +++ b/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml @@ -0,0 +1,56 @@ + + + + + + uuid as "uuid", + kee as "key", + name as "name", + description as "description", + url as "url", + avatar_url as "avatarUrl", + created_at as "createdAt", + updated_at as "updatedAt" + + + + + + + + insert into organizations + ( + uuid, + kee, + name, + description, + url, + avatar_url, + created_at, + updated_at + ) + values + ( + #{organization.uuid, jdbcType=VARCHAR}, + #{organization.key, jdbcType=VARCHAR}, + #{organization.name, jdbcType=VARCHAR}, + #{organization.description, jdbcType=VARCHAR}, + #{organization.url, jdbcType=VARCHAR}, + #{organization.avatarUrl, jdbcType=VARCHAR}, + #{organization.createdAt, jdbcType=BIGINT}, + #{organization.updatedAt, jdbcType=BIGINT} + ) + + diff --git a/sonar-db/src/test/java/org/sonar/db/DaoModuleTest.java b/sonar-db/src/test/java/org/sonar/db/DaoModuleTest.java index 8e7a117b0eb..0b50ebf78c8 100644 --- a/sonar-db/src/test/java/org/sonar/db/DaoModuleTest.java +++ b/sonar-db/src/test/java/org/sonar/db/DaoModuleTest.java @@ -29,6 +29,6 @@ public class DaoModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new DaoModule().configure(container); - assertThat(container.size()).isEqualTo(2 + 50); + assertThat(container.size()).isEqualTo(2 + 51); } } diff --git a/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java b/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java new file mode 100644 index 00000000000..ad77e9b4cbf --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java @@ -0,0 +1,192 @@ +/* + * 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.db.organization; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import org.apache.ibatis.exceptions.PersistenceException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class OrganizationDaoTest { + private static final OrganizationDto ORGANIZATION_DTO = new OrganizationDto() + .setUuid("a uuid") + .setKey("the_key") + .setName("the name") + .setDescription("the description") + .setUrl("the url") + .setAvatarUrl("the avatar url") + .setCreatedAt(1_999_000L) + .setUpdatedAt(1_888_000L); + + @Rule + public final DbTester dbTester = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private DbClient dbClient = dbTester.getDbClient(); + private DbSession dbSession = dbTester.getSession(); + + private OrganizationDao underTest = dbClient.organizationDao(); + + @Test + public void insert_fails_with_NPE_if_OrganizationDto_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("OrganizationDto can't be null"); + + underTest.insert(dbSession, null); + } + + @Test + public void insert_persists_properties_of_OrganizationDto() { + insertOrganization(ORGANIZATION_DTO); + + Map row = selectSingleRow(); + assertThat(row.get("uuid")).isEqualTo(ORGANIZATION_DTO.getUuid()); + assertThat(row.get("key")).isEqualTo(ORGANIZATION_DTO.getKey()); + assertThat(row.get("name")).isEqualTo(ORGANIZATION_DTO.getName()); + assertThat(row.get("description")).isEqualTo(ORGANIZATION_DTO.getDescription()); + assertThat(row.get("url")).isEqualTo(ORGANIZATION_DTO.getUrl()); + assertThat(row.get("avatarUrl")).isEqualTo(ORGANIZATION_DTO.getAvatarUrl()); + assertThat(row.get("createdAt")).isEqualTo(ORGANIZATION_DTO.getCreatedAt()); + assertThat(row.get("updatedAt")).isEqualTo(ORGANIZATION_DTO.getUpdatedAt()); + } + + @Test + public void description_url_and_avatarUrl_are_optional() { + insertOrganization(ORGANIZATION_DTO.setDescription(null).setUrl(null).setAvatarUrl(null)); + + Map row = selectSingleRow(); + assertThat(row.get("uuid")).isEqualTo(ORGANIZATION_DTO.getUuid()); + assertThat(row.get("key")).isEqualTo(ORGANIZATION_DTO.getKey()); + assertThat(row.get("name")).isEqualTo(ORGANIZATION_DTO.getName()); + assertThat(row.get("description")).isNull(); + assertThat(row.get("url")).isNull(); + assertThat(row.get("avatarUrl")).isNull(); + assertThat(row.get("createdAt")).isEqualTo(ORGANIZATION_DTO.getCreatedAt()); + assertThat(row.get("updatedAt")).isEqualTo(ORGANIZATION_DTO.getUpdatedAt()); + } + + @Test + public void insert_fails_if_row_with_uuid_already_exists() { + insertOrganization(ORGANIZATION_DTO); + + OrganizationDto dto = new OrganizationDto() + .setUuid(ORGANIZATION_DTO.getUuid()) + .setKey("other key") + .setName("other name") + .setCreatedAt(2_999_000L) + .setUpdatedAt(2_888_000L); + + expectedException.expect(PersistenceException.class); + + underTest.insert(dbSession, dto); + } + + @Test + public void selectByKey_returns_empty_when_table_is_empty() { + assertThat(underTest.selectByKey(dbSession, ORGANIZATION_DTO.getKey())).isEmpty(); + } + + @Test + public void selectByKey_returns_row_data_when_key_exists() { + insertOrganization(ORGANIZATION_DTO); + + Optional optional = underTest.selectByKey(dbSession, ORGANIZATION_DTO.getKey()); + verify(optional); + } + + @Test + public void selectByKey_returns_row_data_of_specified_key() { + insertOrganization(ORGANIZATION_DTO); + + assertThat(underTest.selectByKey(dbSession, "foo key")).isEmpty(); + } + + @Test + public void selectByLKey_is_case_sensitive() { + insertOrganization(ORGANIZATION_DTO); + + assertThat(underTest.selectByKey(dbSession, ORGANIZATION_DTO.getKey().toUpperCase(Locale.ENGLISH))).isEmpty(); + } + + @Test + public void selectByUuid_returns_empty_when_table_is_empty() { + assertThat(underTest.selectByUuid(dbSession, ORGANIZATION_DTO.getUuid())).isEmpty(); + } + + @Test + public void selectByUuid_returns_row_data_when_uuid_exists() { + insertOrganization(ORGANIZATION_DTO); + + Optional optional = underTest.selectByUuid(dbSession, ORGANIZATION_DTO.getUuid()); + verify(optional); + } + + @Test + public void selectByUuid_returns_row_data_of_specified_uuid() { + insertOrganization(ORGANIZATION_DTO); + + assertThat(underTest.selectByUuid(dbSession, "foo uuid")).isEmpty(); + } + + @Test + public void selectByUuid_is_case_sensitive() { + insertOrganization(ORGANIZATION_DTO); + + assertThat(underTest.selectByUuid(dbSession, ORGANIZATION_DTO.getUuid().toUpperCase(Locale.ENGLISH))).isEmpty(); + } + + private void insertOrganization(OrganizationDto dto) { + underTest.insert(dbSession, dto); + dbSession.commit(); + } + + private void verify(Optional optional) { + assertThat(optional).isNotEmpty(); + OrganizationDto dto = optional.get(); + assertThat(dto.getUuid()).isEqualTo(ORGANIZATION_DTO.getUuid()); + assertThat(dto.getKey()).isEqualTo(ORGANIZATION_DTO.getKey()); + assertThat(dto.getName()).isEqualTo(ORGANIZATION_DTO.getName()); + assertThat(dto.getDescription()).isEqualTo(ORGANIZATION_DTO.getDescription()); + assertThat(dto.getUrl()).isEqualTo(ORGANIZATION_DTO.getUrl()); + assertThat(dto.getAvatarUrl()).isEqualTo(ORGANIZATION_DTO.getAvatarUrl()); + assertThat(dto.getCreatedAt()).isEqualTo(ORGANIZATION_DTO.getCreatedAt()); + assertThat(dto.getUpdatedAt()).isEqualTo(ORGANIZATION_DTO.getUpdatedAt()); + } + + private Map selectSingleRow() { + List> rows = dbTester.select("select" + + " uuid as \"uuid\", kee as \"key\", name as \"name\", description as \"description\", url as \"url\", avatar_url as \"avatarUrl\"," + + " created_at as \"createdAt\", updated_at as \"updatedAt\"" + + " from organizations"); + assertThat(rows).hasSize(1); + return rows.get(0); + } +} -- 2.39.5