]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20315 update scim queries, introduce OffsetBasedPagination
authorPierre <pierre.guillot@sonarsource.com>
Thu, 28 Sep 2023 14:16:58 +0000 (16:16 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 28 Sep 2023 20:03:13 +0000 (20:03 +0000)
12 files changed:
server/sonar-db-dao/src/it/java/org/sonar/db/scim/ScimUserDaoIT.java
server/sonar-db-dao/src/main/java/org/sonar/db/OffsetBasedPagination.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/Pagination.java
server/sonar-db-dao/src/main/java/org/sonar/db/Pagineable.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimGroupDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimGroupMapper.java
server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimUserDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimUserMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/scim/ScimGroupMapper.xml
server/sonar-db-dao/src/main/resources/org/sonar/db/scim/ScimUserMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/OffsetBasedPaginationTest.java [new file with mode: 0644]
server/sonar-db-dao/src/test/java/org/sonar/db/scim/ScimGroupDaoTest.java

index 91390b3b9b2da2d1fc20dbfe37b2b1fb0620fb8c..0530023890b80752e9969fb1483c238d318ad398 100644 (file)
@@ -36,6 +36,8 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
+import org.sonar.db.OffsetBasedPagination;
+import org.sonar.db.Pagination;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 
@@ -111,7 +113,6 @@ public class ScimUserDaoIT {
       {9, 3, 3, List.of("4", "5", "6")},
       {9, 7, 3, List.of("8", "9")},
       {5, 5, 20, List.of()},
-      {5, 0, 0, List.of()},
     };
   }
 
@@ -120,7 +121,7 @@ public class ScimUserDaoIT {
   public void findScimUsers_whenPaginationAndStartIndex_shouldReturnTheCorrectNumberOfScimUsers(int totalScimUsers, int offset, int pageSize, List<String> expectedScimUserUuids) {
     generateScimUsers(totalScimUsers);
 
-    List<ScimUserDto> scimUserDtos = scimUserDao.findScimUsers(dbSession, ScimUserQuery.empty(), offset, pageSize);
+    List<ScimUserDto> scimUserDtos = scimUserDao.findScimUsers(dbSession, ScimUserQuery.empty(), OffsetBasedPagination.forOffset(offset, pageSize));
 
     List<String> scimUsersUuids = toScimUsersUuids(scimUserDtos);
     assertThat(scimUsersUuids).containsExactlyElementsOf(expectedScimUserUuids);
@@ -195,7 +196,7 @@ public class ScimUserDaoIT {
     insertScimUsersWithUsers(userLogins);
     ScimUserQuery query = ScimUserQuery.builder().userName(search).build();
 
-    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, 0, 100);
+    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, Pagination.all());
 
     List<String> scimUsersUuids = toScimUsersUuids(scimUsersByQuery);
     assertThat(scimUsersUuids).containsExactlyElementsOf(expectedScimUserUuids);
@@ -212,7 +213,7 @@ public class ScimUserDaoIT {
 
     ScimUserQuery query = ScimUserQuery.builder().groupUuid(group1dto.getUuid()).build();
 
-    List<ScimUserDto> scimUsers = scimUserDao.findScimUsers(dbSession, query, 0, 100);
+    List<ScimUserDto> scimUsers = scimUserDao.findScimUsers(dbSession, query, Pagination.all());
 
     List<String> scimUsersUuids = toScimUsersUuids(scimUsers);
     assertThat(scimUsersUuids).containsExactlyInAnyOrder(
@@ -238,7 +239,7 @@ public class ScimUserDaoIT {
 
     ScimUserQuery query = ScimUserQuery.builder().scimUserUuids(expectedScimUserUuids).build();
 
-    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, 0, Integer.MAX_VALUE);
+    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, Pagination.all());
 
     List<String> scimUsersUuids = toScimUsersUuids(scimUsersByQuery);
     assertThat(scimUsersByQuery)
@@ -255,7 +256,7 @@ public class ScimUserDaoIT {
 
     ScimUserQuery query = ScimUserQuery.builder().scimUserUuids(scimUserUuids).userName("username_5").build();
 
-    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, 0, Integer.MAX_VALUE);
+    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, Pagination.all());
 
     assertThat(scimUsersByQuery).hasSize(1)
       .extracting(ScimUserDto::getScimUserUuid)
@@ -271,7 +272,7 @@ public class ScimUserDaoIT {
 
     ScimUserQuery query = ScimUserQuery.builder().userUuids(allUsersUuid).build();
 
-    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, 0, Integer.MAX_VALUE);
+    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, Pagination.all());
 
     assertThat(scimUsersByQuery)
       .hasSameSizeAs(allUsersUuid)
@@ -288,7 +289,7 @@ public class ScimUserDaoIT {
 
     ScimUserQuery query = ScimUserQuery.builder().userUuids(allUsersUuid).userName("username_5").build();
 
-    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, 0, Integer.MAX_VALUE);
+    List<ScimUserDto> scimUsersByQuery = scimUserDao.findScimUsers(dbSession, query, Pagination.all());
 
     assertThat(scimUsersByQuery).hasSize(1)
       .extracting(ScimUserDto::getScimUserUuid)
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/OffsetBasedPagination.java b/server/sonar-db-dao/src/main/java/org/sonar/db/OffsetBasedPagination.java
new file mode 100644 (file)
index 0000000..3ba9042
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info 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;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class OffsetBasedPagination implements Pagineable {
+
+  private final int offset;
+  private final int pageSize;
+
+  private OffsetBasedPagination(int offset, int pageSize) {
+    this.offset = offset;
+    this.pageSize = pageSize;
+  }
+
+  /**
+   * @param offset as meant by database sql offset: how many rows will be skipped before selecting the first result. offset=0 means no element would be skipped
+   * @param pageSize how many rows should be returned
+   * @return
+   */
+  public static OffsetBasedPagination forOffset(int offset, int pageSize) {
+    checkArgument(offset >= 0, "offset must be >= 0");
+    checkArgument(pageSize >= 1, "page size must be >= 1");
+    return new OffsetBasedPagination(offset, pageSize);
+  }
+
+  /**
+   * @param startRowNumber index of the first element to be returned. startRowNumber = 1 means no element would be skipped
+   * @param pageSize how many rows should be returned
+   * @return
+   */
+  public static OffsetBasedPagination forStartRowNumber(int startRowNumber, int pageSize) {
+    checkArgument(startRowNumber >= 1, "startRowNumber must be >= 1");
+    checkArgument(pageSize >= 1, "page size must be >= 1");
+    return new OffsetBasedPagination(startRowNumber - 1, pageSize);
+  }
+
+  @Override
+  public int getStartRowNumber() {
+    return offset + 1;
+  }
+
+  @Override
+  public int getOffset() {
+    return offset;
+  }
+
+  @Override
+  public int getPageSize() {
+    return pageSize;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    OffsetBasedPagination that = (OffsetBasedPagination) o;
+    return offset == that.offset && pageSize == that.pageSize;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(offset, pageSize);
+  }
+}
index bf1f260add7265f0935cd7f38cea5ee5acabad59..5ee079241a25d4b98a8bcabd232d49038abd4cfa 100644 (file)
@@ -24,7 +24,7 @@ import javax.annotation.concurrent.Immutable;
 import static com.google.common.base.Preconditions.checkArgument;
 
 @Immutable
-public final class Pagination {
+public final class Pagination implements Pagineable {
   private static final Pagination ALL = new Builder(1).andSize(Integer.MAX_VALUE);
 
   private static final Pagination FIRST = new Builder(1).andSize(1);
@@ -53,14 +53,17 @@ public final class Pagination {
     return page;
   }
 
+  @Override
   public int getPageSize() {
     return pageSize;
   }
 
+  @Override
   public int getOffset() {
     return (page - 1) * pageSize;
   }
 
+  @Override
   public int getStartRowNumber() {
     return getOffset() + 1;
   }
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/Pagineable.java b/server/sonar-db-dao/src/main/java/org/sonar/db/Pagineable.java
new file mode 100644 (file)
index 0000000..5bba0a4
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info 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;
+
+public interface Pagineable {
+
+  int getStartRowNumber();
+
+  int getOffset();
+
+  int getPageSize();
+
+}
index ae1a8be730e58b39188aac5327f6b84afc7c19de..e3000bef8380cd1cdd6602fa8714e0114bb33dbf 100644 (file)
@@ -21,10 +21,10 @@ package org.sonar.db.scim;
 
 import java.util.List;
 import java.util.Optional;
-import org.apache.ibatis.session.RowBounds;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.db.Dao;
 import org.sonar.db.DbSession;
+import org.sonar.db.Pagineable;
 
 public class ScimGroupDao implements Dao {
   private final UuidFactory uuidFactory;
@@ -37,8 +37,8 @@ public class ScimGroupDao implements Dao {
     return mapper(dbSession).findAll();
   }
 
-  public List<ScimGroupDto> findScimGroups(DbSession dbSession, ScimGroupQuery query, int offset, int limit) {
-    return mapper(dbSession).findScimGroups(query, new RowBounds(offset, limit));
+  public List<ScimGroupDto> findScimGroups(DbSession dbSession, ScimGroupQuery query, Pagineable pagination) {
+    return mapper(dbSession).findScimGroups(query, pagination);
   }
 
   public Optional<ScimGroupDto> findByScimUuid(DbSession dbSession, String scimGroupUuid) {
index ec52527f85636dc49a734cc13dfcae828e4e9b68..8d87f514e5fc45b6ecc09a3bd1832a6c907262d0 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.db.scim;
 import java.util.List;
 import javax.annotation.CheckForNull;
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.session.RowBounds;
+import org.sonar.db.Pagineable;
 
 public interface ScimGroupMapper {
 
@@ -34,7 +34,7 @@ public interface ScimGroupMapper {
   @CheckForNull
   ScimGroupDto findByGroupUuid(@Param("groupUuid") String groupUuid);
 
-  List<ScimGroupDto> findScimGroups(@Param("query") ScimGroupQuery query, RowBounds rowBounds);
+  List<ScimGroupDto> findScimGroups(@Param("query") ScimGroupQuery query, @Param("pagination") Pagineable pagination);
 
   int countScimGroups(@Param("query") ScimGroupQuery query);
 
index c68481ae812c593e36568af62e19efad95a83f3b..1aaa9d664735c853ca14bab07fd76935c72d3697 100644 (file)
@@ -23,10 +23,10 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
 import java.util.function.BiFunction;
-import org.apache.ibatis.session.RowBounds;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.db.Dao;
 import org.sonar.db.DbSession;
+import org.sonar.db.Pagineable;
 
 import static org.sonar.api.utils.Preconditions.checkState;
 import static org.sonar.db.DatabaseUtils.executeLargeInputs;
@@ -56,7 +56,7 @@ public class ScimUserDao implements Dao {
     return scimUserDto;
   }
 
-  public List<ScimUserDto> findScimUsers(DbSession dbSession, ScimUserQuery scimUserQuery, int offset, int limit) {
+  public List<ScimUserDto> findScimUsers(DbSession dbSession, ScimUserQuery scimUserQuery, Pagineable pagination) {
     checkState(scimUserQuery.getUserUuids() == null || scimUserQuery.getScimUserUuids() == null,
       "Only one of userUuids & scimUserUuids request parameter is supported.");
     if (scimUserQuery.getScimUserUuids() != null) {
@@ -64,7 +64,7 @@ public class ScimUserDao implements Dao {
         scimUserQuery.getScimUserUuids(),
         partialSetOfUsers -> createPartialQuery(scimUserQuery, partialSetOfUsers,
           (builder, scimUserUuids) -> builder.scimUserUuids(new HashSet<>(scimUserUuids)),
-          dbSession, offset, limit)
+          dbSession, pagination)
       );
     }
     if (scimUserQuery.getUserUuids() != null) {
@@ -72,20 +72,21 @@ public class ScimUserDao implements Dao {
         scimUserQuery.getUserUuids(),
         partialSetOfUsers -> createPartialQuery(scimUserQuery, partialSetOfUsers,
           (builder, userUuids) -> builder.userUuids(new HashSet<>(userUuids)),
-          dbSession, offset, limit)
+          dbSession, pagination)
       );
     }
-    return mapper(dbSession).findScimUsers(scimUserQuery, new RowBounds(offset, limit));
+
+    return mapper(dbSession).findScimUsers(scimUserQuery, pagination);
   }
 
   private static List<ScimUserDto> createPartialQuery(ScimUserQuery completeQuery, List<String> strings,
     BiFunction<ScimUserQuery.ScimUserQueryBuilder, List<String>, ScimUserQuery.ScimUserQueryBuilder> queryModifier,
-    DbSession dbSession, int offset, int limit) {
+    DbSession dbSession, Pagineable pagination) {
 
     ScimUserQuery.ScimUserQueryBuilder partialScimUserQuery = ScimUserQuery.builder()
       .userName(completeQuery.getUserName());
     partialScimUserQuery = queryModifier.apply(partialScimUserQuery, strings);
-    return mapper(dbSession).findScimUsers(partialScimUserQuery.build(), new RowBounds(offset, limit));
+    return mapper(dbSession).findScimUsers(partialScimUserQuery.build(), pagination);
   }
 
   public int countScimUsers(DbSession dbSession, ScimUserQuery scimUserQuery) {
index 8fe42ca6f90a57bd68c3b8f2ccfe9fb243c7bb28..87ef3285dd11bcd5aadcece4f3b9c40d368019c8 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.db.scim;
 import java.util.List;
 import javax.annotation.CheckForNull;
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.session.RowBounds;
+import org.sonar.db.Pagineable;
 
 public interface ScimUserMapper {
 
@@ -36,7 +36,7 @@ public interface ScimUserMapper {
 
   void insert(@Param("scimUserDto") ScimUserDto scimUserDto);
 
-  List<ScimUserDto> findScimUsers(@Param("query") ScimUserQuery scimUserQuery, RowBounds rowBounds);
+  List<ScimUserDto> findScimUsers(@Param("query") ScimUserQuery scimUserQuery, @Param("pagination") Pagineable pagination);
 
   int countScimUsers(@Param("query") ScimUserQuery scimUserQuery);
 
index 779940e91f19e684c9222f611361a6c925224fd5..44fd376acafdf6dbb32a59f1130f30988666c003 100644 (file)
       where g.name = #{query.displayName,jdbcType=VARCHAR}
     </if>
     order by s.scim_uuid asc
+    <include refid="pagination"/>
   </select>
 
+  <sql id="pagination">
+    offset #{pagination.offset,jdbcType=INTEGER} rows fetch next #{pagination.pageSize,jdbcType=INTEGER} rows only
+  </sql>
+
   <select id="countScimGroups" resultType="int">
     select count(1)
     from scim_groups s
index 97a61c41d2efa105752f49dc9c71d5cca50d6a5a..8c1e7b4f3fd9c56acfdfa2f4aba0408de47c6b3f 100644 (file)
     )
   </insert>
 
-  <select id="findScimUsers" parameterType="map" resultType="org.sonar.db.scim.ScimUserDto">
+  <select id="findScimUsers" resultType="org.sonar.db.scim.ScimUserDto">
     select
     <include refid="scimUsersColumns"/>
     <include refid="sqlSelectByQuery"/>
     order by s.scim_uuid asc
+    <include refid="pagination"/>
   </select>
 
+  <sql id="pagination">
+    offset #{pagination.offset,jdbcType=INTEGER} rows fetch next #{pagination.pageSize,jdbcType=INTEGER} rows only
+  </sql>
+
   <select id="countScimUsers" parameterType="map" resultType="int">
     select count(1)
     <include refid="sqlSelectByQuery"/>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/OffsetBasedPaginationTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/OffsetBasedPaginationTest.java
new file mode 100644 (file)
index 0000000..88c412a
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info 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;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class OffsetBasedPaginationTest {
+
+  @Test
+  public void forOffset_whenNegativeOffset_shouldfailsWithIAE() {
+    assertThatThrownBy(() -> OffsetBasedPagination.forOffset(-1, 10))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("offset must be >= 0");
+  }
+
+  @Test
+  public void forOffset_whenPageSizeIsZero_shouldfailsWithIAE() {
+    assertThatThrownBy(() -> OffsetBasedPagination.forOffset(1, 0))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("page size must be >= 1");
+  }
+
+  @Test
+  public void forOffset_whenNegativePageSize_shouldfailsWithIAE() {
+    assertThatThrownBy(() -> OffsetBasedPagination.forOffset(1, -1))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("page size must be >= 1");
+  }
+
+  @Test
+  public void forOffset_whenZeroOffset_shouldStartRowNumberAtOne() {
+    assertThat(OffsetBasedPagination.forOffset(0, 100))
+      .extracting(p -> p.getStartRowNumber(), p -> p.getOffset(), p -> p.getPageSize())
+      .containsExactly(1, 0, 100);
+  }
+
+  @Test
+  public void forStartRowNumber_whenStartRowNumberLowerThanOne_shouldfailsWithIAE() {
+    assertThatThrownBy(() -> OffsetBasedPagination.forStartRowNumber(0, 10))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("startRowNumber must be >= 1");
+  }
+
+  @Test
+  public void forStartRowNumber_whenPageSizeIsZero_shouldfailsWithIAE() {
+    assertThatThrownBy(() -> OffsetBasedPagination.forStartRowNumber(1, 0))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("page size must be >= 1");
+  }
+
+  @Test
+  public void forStartRowNumber_whenNegativePageSize_shouldfailsWithIAE() {
+    assertThatThrownBy(() -> OffsetBasedPagination.forStartRowNumber(1, -1))
+      .isInstanceOf(IllegalArgumentException.class)
+      .hasMessage("page size must be >= 1");
+  }
+
+  @Test
+  public void forStartRowNumber_whenZeroOffset_shouldStartRowNumberAtOne() {
+    assertThat(OffsetBasedPagination.forStartRowNumber(1, 100))
+      .extracting(p -> p.getStartRowNumber(), p -> p.getOffset(), p -> p.getPageSize())
+      .containsExactly(1, 0, 100);
+  }
+
+  @Test
+  public void equals_whenSameParameters_shouldBeTrue() {
+    Assertions.assertThat(OffsetBasedPagination.forStartRowNumber(15, 20))
+      .isEqualTo(OffsetBasedPagination.forOffset(14, 20));
+  }
+
+  @Test
+  public void equals_whenSameObjects_shouldBeTrue() {
+    OffsetBasedPagination offsetBasedPagination = OffsetBasedPagination.forStartRowNumber(15, 20);
+    Assertions.assertThat(offsetBasedPagination).isEqualTo(offsetBasedPagination);
+  }
+
+  @Test
+  public void hashcode_whenSameObjects_shouldBeEquals() {
+    OffsetBasedPagination offsetBasedPagination = OffsetBasedPagination.forStartRowNumber(15, 20);
+    Assertions.assertThat(offsetBasedPagination).hasSameHashCodeAs(offsetBasedPagination);
+  }
+
+  @Test
+  public void equals_whenDifferentClasses_shouldBeFalse() {
+    Assertions.assertThat(OffsetBasedPagination.forStartRowNumber(15, 20)).isNotEqualTo("not an OffsetBasedPagination object");
+  }
+
+  @Test
+  public void equals_whenDifferentPageSize_shouldBeFalse() {
+    Assertions.assertThat(OffsetBasedPagination.forStartRowNumber(15, 21))
+      .isNotEqualTo(OffsetBasedPagination.forOffset(14, 20));
+  }
+
+  @Test
+  public void equals_whenDifferentOffset_shouldBeFalse() {
+    Assertions.assertThat(OffsetBasedPagination.forOffset(30, 20))
+      .isNotEqualTo(OffsetBasedPagination.forOffset(15, 20));
+  }
+
+  @Test
+  public void hashcode_whenSameParameters_shouldBeEquals() {
+    Assertions.assertThat(OffsetBasedPagination.forStartRowNumber(1, 20))
+      .hasSameHashCodeAs(OffsetBasedPagination.forOffset(0, 20));
+  }
+
+  @Test
+  public void hashcode_whenDifferentOffset_shouldBeNotEquals() {
+    Assertions.assertThat(OffsetBasedPagination.forOffset(10, 20))
+      .doesNotHaveSameHashCodeAs(OffsetBasedPagination.forOffset(15, 20));
+  }
+
+  @Test
+  public void hashcode_whenDifferentPageSize_shouldBeNotEquals() {
+    Assertions.assertThat(OffsetBasedPagination.forOffset(0, 20))
+      .doesNotHaveSameHashCodeAs(OffsetBasedPagination.forOffset(0, 40));
+  }
+
+
+
+}
index 6d9dda3dcbd1015cbc5c0a9edd0795926cfebce3..bef943f7757272b42bf27a23ae76a8a67d7d1c21 100644 (file)
@@ -31,6 +31,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.sonar.db.DbTester;
+import org.sonar.db.OffsetBasedPagination;
+import org.sonar.db.Pagination;
 import org.sonar.db.user.GroupDto;
 
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
@@ -85,8 +87,7 @@ public class ScimGroupDaoTest {
       {9, 0, 5, List.of("1", "2", "3", "4", "5")},
       {9, 3, 3, List.of("4", "5", "6")},
       {9, 7, 3, List.of("8", "9")},
-      {5, 5, 20, List.of()},
-      {5, 0, 0, List.of()}
+      {5, 5, 20, List.of()}
     };
   }
 
@@ -96,7 +97,7 @@ public class ScimGroupDaoTest {
     List<String> expectedScimGroupUuidSuffixes) {
     generateScimGroups(totalScimGroups);
 
-    List<ScimGroupDto> scimGroupDtos = scimGroupDao.findScimGroups(db.getSession(), ScimGroupQuery.ALL, offset, pageSize);
+    List<ScimGroupDto> scimGroupDtos = scimGroupDao.findScimGroups(db.getSession(), ScimGroupQuery.ALL, OffsetBasedPagination.forOffset(offset, pageSize));
 
     List<String> actualScimGroupsUuids = toScimGroupsUuids(scimGroupDtos);
     List<String> expectedScimGroupUuids = toExpectedscimGroupUuids(expectedScimGroupUuidSuffixes);
@@ -115,7 +116,7 @@ public class ScimGroupDaoTest {
     insertGroupAndScimGroup("group2");
     ScimGroupQuery query = ScimGroupQuery.fromScimFilter(DISPLAY_NAME_FILTER);
 
-    List<ScimGroupDto> scimGroups = scimGroupDao.findScimGroups(db.getSession(), query, 0, 100);
+    List<ScimGroupDto> scimGroups = scimGroupDao.findScimGroups(db.getSession(), query, Pagination.all());
 
     assertThat(scimGroups).hasSize(1);
     assertThat(scimGroups.get(0).getScimGroupUuid()).isEqualTo(createScimGroupUuid("group2"));