mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 03:39:26 +00:00
Optimize search
This commit is contained in:
@@ -3,5 +3,8 @@ package com.imgfloat.app.repository;
|
|||||||
import com.imgfloat.app.model.Channel;
|
import com.imgfloat.app.model.Channel;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface ChannelRepository extends JpaRepository<Channel, String> {
|
public interface ChannelRepository extends JpaRepository<Channel, String> {
|
||||||
|
List<Channel> findTop50ByBroadcasterContainingIgnoreCaseOrderByBroadcasterAsc(String broadcasterFragment);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import java.util.Collection;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.imageio.ImageReader;
|
import javax.imageio.ImageReader;
|
||||||
@@ -94,13 +93,10 @@ public class ChannelDirectoryService {
|
|||||||
|
|
||||||
public List<String> searchBroadcasters(String query) {
|
public List<String> searchBroadcasters(String query) {
|
||||||
String normalizedQuery = normalize(query);
|
String normalizedQuery = normalize(query);
|
||||||
return channelRepository.findAll().stream()
|
String searchTerm = normalizedQuery == null || normalizedQuery.isBlank() ? "" : normalizedQuery;
|
||||||
|
return channelRepository.findTop50ByBroadcasterContainingIgnoreCaseOrderByBroadcasterAsc(searchTerm)
|
||||||
|
.stream()
|
||||||
.map(Channel::getBroadcaster)
|
.map(Channel::getBroadcaster)
|
||||||
.map(this::normalize)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.filter(name -> normalizedQuery == null || normalizedQuery.isBlank() || name.contains(normalizedQuery))
|
|
||||||
.sorted()
|
|
||||||
.limit(50)
|
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.imgfloat.app;
|
||||||
|
|
||||||
|
import com.imgfloat.app.model.Channel;
|
||||||
|
import com.imgfloat.app.repository.ChannelRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@SpringBootTest(properties = {
|
||||||
|
"spring.security.oauth2.client.registration.twitch.client-id=test-client-id",
|
||||||
|
"spring.security.oauth2.client.registration.twitch.client-secret=test-client-secret"
|
||||||
|
})
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
class ChannelDirectoryApiIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelRepository channelRepository;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void cleanChannels() {
|
||||||
|
channelRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void searchesBroadcastersCaseInsensitiveAndSorted() throws Exception {
|
||||||
|
channelRepository.save(new Channel("Beta"));
|
||||||
|
channelRepository.save(new Channel("alpha"));
|
||||||
|
channelRepository.save(new Channel("ALPINE"));
|
||||||
|
|
||||||
|
mockMvc.perform(get("/api/channels").param("q", "Al"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", hasSize(2)))
|
||||||
|
.andExpect(jsonPath("$[0]").value("alpha"))
|
||||||
|
.andExpect(jsonPath("$[1]").value("alpine"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -172,6 +173,13 @@ class ChannelDirectoryServiceTest {
|
|||||||
});
|
});
|
||||||
when(channelRepository.findAll())
|
when(channelRepository.findAll())
|
||||||
.thenAnswer(invocation -> List.copyOf(channels.values()));
|
.thenAnswer(invocation -> List.copyOf(channels.values()));
|
||||||
|
when(channelRepository.findTop50ByBroadcasterContainingIgnoreCaseOrderByBroadcasterAsc(anyString()))
|
||||||
|
.thenAnswer(invocation -> channels.values().stream()
|
||||||
|
.filter(channel -> Optional.ofNullable(channel.getBroadcaster()).orElse("")
|
||||||
|
.contains(Optional.ofNullable(invocation.getArgument(0, String.class)).orElse("").toLowerCase()))
|
||||||
|
.sorted(Comparator.comparing(Channel::getBroadcaster))
|
||||||
|
.limit(50)
|
||||||
|
.toList());
|
||||||
|
|
||||||
when(assetRepository.save(any(Asset.class)))
|
when(assetRepository.save(any(Asset.class)))
|
||||||
.thenAnswer(invocation -> {
|
.thenAnswer(invocation -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user