From eac0e9551cbda3f3f05d40e4079f65a0409aacdc Mon Sep 17 00:00:00 2001 From: Junghoon Ban Date: Wed, 8 Jan 2025 21:43:49 +0900 Subject: [PATCH 1/3] Create integration test for sortable entity. --- .../data/meilisearch/entities/Movie.java | 2 - .../meilisearch/entities/SortableMovie.java | 23 +++ ...MeilisearchRepositoryIntegrationTests.java | 81 ---------- ...MeilisearchRepositoryIntegrationTests.java | 142 ++++++++++++++++++ 4 files changed, 165 insertions(+), 83 deletions(-) create mode 100644 src/test/java/io/vanslog/spring/data/meilisearch/entities/SortableMovie.java create mode 100644 src/test/java/io/vanslog/spring/data/meilisearch/repository/SortableMeilisearchRepositoryIntegrationTests.java diff --git a/src/test/java/io/vanslog/spring/data/meilisearch/entities/Movie.java b/src/test/java/io/vanslog/spring/data/meilisearch/entities/Movie.java index 163f2643..853aa7d3 100644 --- a/src/test/java/io/vanslog/spring/data/meilisearch/entities/Movie.java +++ b/src/test/java/io/vanslog/spring/data/meilisearch/entities/Movie.java @@ -16,7 +16,6 @@ package io.vanslog.spring.data.meilisearch.entities; import io.vanslog.spring.data.meilisearch.annotations.Document; -import io.vanslog.spring.data.meilisearch.annotations.Setting; import java.util.Arrays; import java.util.Objects; @@ -28,7 +27,6 @@ * * @author Junghoon Ban */ -@Setting(sortAttributes = { "title" }) @Document(indexUid = "movies") @SuppressWarnings("unused") public class Movie { diff --git a/src/test/java/io/vanslog/spring/data/meilisearch/entities/SortableMovie.java b/src/test/java/io/vanslog/spring/data/meilisearch/entities/SortableMovie.java new file mode 100644 index 00000000..a9114676 --- /dev/null +++ b/src/test/java/io/vanslog/spring/data/meilisearch/entities/SortableMovie.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.vanslog.spring.data.meilisearch.entities; + +import io.vanslog.spring.data.meilisearch.annotations.Document; +import io.vanslog.spring.data.meilisearch.annotations.Setting; + +@Setting(sortAttributes = { "title" }) +@Document(indexUid = "movies") +public class SortableMovie extends Movie {} diff --git a/src/test/java/io/vanslog/spring/data/meilisearch/repository/MeilisearchRepositoryIntegrationTests.java b/src/test/java/io/vanslog/spring/data/meilisearch/repository/MeilisearchRepositoryIntegrationTests.java index 51ade348..327a05dd 100644 --- a/src/test/java/io/vanslog/spring/data/meilisearch/repository/MeilisearchRepositoryIntegrationTests.java +++ b/src/test/java/io/vanslog/spring/data/meilisearch/repository/MeilisearchRepositoryIntegrationTests.java @@ -33,7 +33,6 @@ import org.springframework.context.annotation.Import; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; import org.springframework.test.context.ContextConfiguration; /** @@ -301,86 +300,6 @@ void shouldFindDocumentsWithPaging() { assertThat(page2.getContent().get(0)).isEqualTo(movie3); } - @Test - void shouldFindDocumentsWithSorting() { - // given - int documentId1 = 1; - Movie movie1 = new Movie(); - movie1.setId(documentId1); - movie1.setTitle("Carol"); - movie1.setDescription("A love story"); - movie1.setGenres(new String[] { "Romance", "Drama" }); - - int documentId2 = 2; - Movie movie2 = new Movie(); - movie2.setId(documentId2); - movie2.setTitle("Wonder Woman"); - movie2.setDescription("A superhero film"); - movie2.setGenres(new String[] { "Action", "Adventure" }); - - int documentId3 = 3; - Movie movie3 = new Movie(); - movie3.setId(documentId3); - movie3.setTitle("Life of Pi"); - movie3.setDescription("A survival film"); - movie3.setGenres(new String[] { "Adventure", "Drama" }); - - List movies = List.of(movie1, movie3, movie2); - movieRepository.saveAll(movies); - - // when - Iterable descOrdered = movieRepository.findAll(Sort.by(Sort.Direction.DESC, "title")); - Iterable ascOrdered = movieRepository.findAll(Sort.by(Sort.Direction.ASC, "title")); - - // then - assertThat(descOrdered).hasSize(3).containsExactly(movie2, movie3, movie1); - assertThat(ascOrdered).hasSize(3).containsExactly(movie1, movie3, movie2); - } - - @Test - void shouldFindDocumentsWithPagingAndSorting() { - // given - int pagingSize = 2; - - int documentId1 = 1; - Movie movie1 = new Movie(); - movie1.setId(documentId1); - movie1.setTitle("Carol"); - movie1.setDescription("A love story"); - movie1.setGenres(new String[] { "Romance", "Drama" }); - - int documentId2 = 2; - Movie movie2 = new Movie(); - movie2.setId(documentId2); - movie2.setTitle("Wonder Woman"); - movie2.setDescription("A superhero film"); - movie2.setGenres(new String[] { "Action", "Adventure" }); - - int documentId3 = 3; - Movie movie3 = new Movie(); - movie3.setId(documentId3); - movie3.setTitle("Life of Pi"); - movie3.setDescription("A survival film"); - movie3.setGenres(new String[] { "Adventure", "Drama" }); - - List movies = List.of(movie1, movie2, movie3); - movieRepository.saveAll(movies); - - // when - Page page1 = movieRepository.findAll(PageRequest.of(0, pagingSize, Sort.by(Sort.Direction.ASC, "title"))); - Page page2 = movieRepository.findAll(PageRequest.of(1, pagingSize, Sort.by(Sort.Direction.ASC, "title"))); - - // then - assertThat(page1.getTotalElements()).isEqualTo(movies.size()); - - assertThat(page1.getContent()).hasSize(2); - assertThat(page1.getContent().get(0)).isEqualTo(movie1); - assertThat(page1.getContent().get(1)).isEqualTo(movie3); - - assertThat(page2.getContent()).hasSize(1); - assertThat(page2.getContent().get(0)).isEqualTo(movie2); - } - @Test void shouldNotSearchAllElementsWhenMaxTotalHitsAre10() { // given diff --git a/src/test/java/io/vanslog/spring/data/meilisearch/repository/SortableMeilisearchRepositoryIntegrationTests.java b/src/test/java/io/vanslog/spring/data/meilisearch/repository/SortableMeilisearchRepositoryIntegrationTests.java new file mode 100644 index 00000000..6dfda968 --- /dev/null +++ b/src/test/java/io/vanslog/spring/data/meilisearch/repository/SortableMeilisearchRepositoryIntegrationTests.java @@ -0,0 +1,142 @@ +/* + * Copyright 2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.vanslog.spring.data.meilisearch.repository; + +import static org.assertj.core.api.Assertions.*; + +import io.vanslog.spring.data.meilisearch.entities.SortableMovie; +import io.vanslog.spring.data.meilisearch.junit.jupiter.MeilisearchTest; +import io.vanslog.spring.data.meilisearch.junit.jupiter.MeilisearchTestConfiguration; +import io.vanslog.spring.data.meilisearch.repository.config.EnableMeilisearchRepositories; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.test.context.ContextConfiguration; + +/** + * Integration tests for {@link MeilisearchRepository}. + * + * @author Junghoon Ban + */ +@MeilisearchTest +@ContextConfiguration(classes = SortableMeilisearchRepositoryIntegrationTests.Config.class) +class SortableMeilisearchRepositoryIntegrationTests { + + @Autowired private SortableMovieRepository movieRepository; + + @BeforeEach + void setUp() { + movieRepository.deleteAll(); + } + + @Test + void shouldFindDocumentsWithSorting() { + // given + int documentId1 = 1; + SortableMovie movie1 = new SortableMovie(); + movie1.setId(documentId1); + movie1.setTitle("Carol"); + movie1.setDescription("A love story"); + movie1.setGenres(new String[] { "Romance", "Drama" }); + + int documentId2 = 2; + SortableMovie movie2 = new SortableMovie(); + movie2.setId(documentId2); + movie2.setTitle("Wonder Woman"); + movie2.setDescription("A superhero film"); + movie2.setGenres(new String[] { "Action", "Adventure" }); + + int documentId3 = 3; + SortableMovie movie3 = new SortableMovie(); + movie3.setId(documentId3); + movie3.setTitle("Life of Pi"); + movie3.setDescription("A survival film"); + movie3.setGenres(new String[] { "Adventure", "Drama" }); + + List movies = List.of(movie1, movie3, movie2); + movieRepository.saveAll(movies); + + // when + Iterable descOrdered = movieRepository.findAll(Sort.by(Sort.Direction.DESC, "title")); + Iterable ascOrdered = movieRepository.findAll(Sort.by(Sort.Direction.ASC, "title")); + + // then + assertThat(descOrdered).hasSize(3).containsExactly(movie2, movie3, movie1); + assertThat(ascOrdered).hasSize(3).containsExactly(movie1, movie3, movie2); + } + + @Test + void shouldFindDocumentsWithPagingAndSorting() { + // given + int pagingSize = 2; + + int documentId1 = 1; + SortableMovie movie1 = new SortableMovie(); + movie1.setId(documentId1); + movie1.setTitle("Carol"); + movie1.setDescription("A love story"); + movie1.setGenres(new String[] { "Romance", "Drama" }); + + int documentId2 = 2; + SortableMovie movie2 = new SortableMovie(); + movie2.setId(documentId2); + movie2.setTitle("Wonder Woman"); + movie2.setDescription("A superhero film"); + movie2.setGenres(new String[] { "Action", "Adventure" }); + + int documentId3 = 3; + SortableMovie movie3 = new SortableMovie(); + movie3.setId(documentId3); + movie3.setTitle("Life of Pi"); + movie3.setDescription("A survival film"); + movie3.setGenres(new String[] { "Adventure", "Drama" }); + + List movies = List.of(movie1, movie2, movie3); + movieRepository.saveAll(movies); + + // when + Page page1 = movieRepository + .findAll(PageRequest.of(0, pagingSize, Sort.by(Sort.Direction.ASC, "title"))); + Page page2 = movieRepository + .findAll(PageRequest.of(1, pagingSize, Sort.by(Sort.Direction.ASC, "title"))); + + // then + assertThat(page1.getTotalElements()).isEqualTo(movies.size()); + + assertThat(page1.getContent()).hasSize(2); + assertThat(page1.getContent().get(0)).isEqualTo(movie1); + assertThat(page1.getContent().get(1)).isEqualTo(movie3); + + assertThat(page2.getContent()).hasSize(1); + assertThat(page2.getContent().get(0)).isEqualTo(movie2); + } + + interface SortableMovieRepository extends MeilisearchRepository {} + + @Configuration + @Import(MeilisearchTestConfiguration.class) + @EnableMeilisearchRepositories(basePackages = "io.vanslog.spring.data.meilisearch.repository", + considerNestedRepositories = true) + static class Config {} +} From 69018aed743a0568df0441c73e67a7d69ec05f5f Mon Sep 17 00:00:00 2001 From: Junghoon Ban Date: Wed, 8 Jan 2025 23:25:47 +0900 Subject: [PATCH 2/3] Add null handling for pagination param in setting annotation. --- .../mapping/SimpleMeilisearchPersistentEntity.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java b/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java index 290c4e4e..1f664bd2 100644 --- a/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java +++ b/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java @@ -142,7 +142,7 @@ private static class SettingsParameter { private String[] displayedAttributes; private String[] rankingRules; @Nullable private String[] stopWords; - private Pagination pagination; + @Nullable private Pagination pagination; Settings toSettings() { Settings settings = new Settings(); @@ -161,9 +161,11 @@ Settings toSettings() { settings.setStopWords(stopWords); } - var meiliPagination = new com.meilisearch.sdk.model.Pagination(); - meiliPagination.setMaxTotalHits(this.pagination.maxTotalHits()); - settings.setPagination(meiliPagination); + if (pagination != null) { + var meiliPagination = new com.meilisearch.sdk.model.Pagination(); + meiliPagination.setMaxTotalHits(this.pagination.maxTotalHits()); + settings.setPagination(meiliPagination); + } return settings; } From 532f0f1dd7c9410e6bc807b727fbf7b236e41d2f Mon Sep 17 00:00:00 2001 From: Junghoon Ban Date: Thu, 9 Jan 2025 00:22:30 +0900 Subject: [PATCH 3/3] Rename method to build SettingsParameter. --- .../core/mapping/SimpleMeilisearchPersistentEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java b/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java index 1f664bd2..60da42e3 100644 --- a/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java +++ b/src/main/java/io/vanslog/spring/data/meilisearch/core/mapping/SimpleMeilisearchPersistentEntity.java @@ -61,7 +61,7 @@ public SimpleMeilisearchPersistentEntity(TypeInformation information) { Class rawType = information.getType(); document = AnnotatedElementUtils.findMergedAnnotation(rawType, Document.class); - this.settingParameter = Lazy.of(() -> buildSettingParameter(rawType)); + this.settingParameter = Lazy.of(() -> buildSettingsParameter(rawType)); if (document != null) { Assert.hasText(document.indexUid(), @@ -95,7 +95,7 @@ public Settings getDefaultSettings() { return settingParameter.get().toSettings(); } - private SettingsParameter buildSettingParameter(Class clazz) { + private SettingsParameter buildSettingsParameter(Class clazz) { SettingsParameter settingsParameter = new SettingsParameter(); Setting settingAnnotation = AnnotatedElementUtils.findMergedAnnotation(clazz, Setting.class);