Improvements, Fixes.
This commit is contained in:
@@ -4,7 +4,6 @@ import com.storycove.entity.Author;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.storycove.repository;
|
|||||||
|
|
||||||
import com.storycove.entity.Collection;
|
import com.storycove.entity.Collection;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.storycove.entity.Tag;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ public class AuthorService {
|
|||||||
rating, author.getName(), author.getAuthorRating());
|
rating, author.getName(), author.getAuthorRating());
|
||||||
|
|
||||||
author.setAuthorRating(rating);
|
author.setAuthorRating(rating);
|
||||||
Author savedAuthor = authorRepository.save(author);
|
authorRepository.save(author);
|
||||||
|
|
||||||
// Flush and refresh to ensure the entity is up-to-date
|
// Flush and refresh to ensure the entity is up-to-date
|
||||||
authorRepository.flush();
|
authorRepository.flush();
|
||||||
|
|||||||
@@ -11,14 +11,10 @@ import com.storycove.repository.CollectionRepository;
|
|||||||
import com.storycove.repository.CollectionStoryRepository;
|
import com.storycove.repository.CollectionStoryRepository;
|
||||||
import com.storycove.repository.StoryRepository;
|
import com.storycove.repository.StoryRepository;
|
||||||
import com.storycove.repository.TagRepository;
|
import com.storycove.repository.TagRepository;
|
||||||
import com.storycove.service.exception.DuplicateResourceException;
|
|
||||||
import com.storycove.service.exception.ResourceNotFoundException;
|
import com.storycove.service.exception.ResourceNotFoundException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -266,7 +262,7 @@ public class CollectionService {
|
|||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void reorderStories(UUID collectionId, List<Map<String, Object>> storyOrders) {
|
public void reorderStories(UUID collectionId, List<Map<String, Object>> storyOrders) {
|
||||||
Collection collection = findByIdBasic(collectionId);
|
findByIdBasic(collectionId); // Validate collection exists
|
||||||
|
|
||||||
// Two-phase update to avoid unique constraint violations:
|
// Two-phase update to avoid unique constraint violations:
|
||||||
// Phase 1: Set all positions to negative values (temporary)
|
// Phase 1: Set all positions to negative values (temporary)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.storycove.service;
|
package com.storycove.service;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.storycove.entity.*;
|
|
||||||
import com.storycove.repository.*;
|
import com.storycove.repository.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -587,6 +586,7 @@ public class DatabaseManagementService {
|
|||||||
// Validate metadata
|
// Validate metadata
|
||||||
try {
|
try {
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> metadata = mapper.readValue(Files.newInputStream(metadataFile), Map.class);
|
Map<String, Object> metadata = mapper.readValue(Files.newInputStream(metadataFile), Map.class);
|
||||||
|
|
||||||
String format = (String) metadata.get("format");
|
String format = (String) metadata.get("format");
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ import java.io.InputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import jakarta.validation.Valid;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -124,7 +123,7 @@ public class StoryService {
|
|||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public List<Story> findBySeries(UUID seriesId) {
|
public List<Story> findBySeries(UUID seriesId) {
|
||||||
Series series = seriesService.findById(seriesId);
|
seriesService.findById(seriesId); // Validate series exists
|
||||||
return storyRepository.findBySeriesOrderByVolume(seriesId);
|
return storyRepository.findBySeriesOrderByVolume(seriesId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ public class TagService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeAlias(UUID tagId, UUID aliasId) {
|
public void removeAlias(UUID tagId, UUID aliasId) {
|
||||||
Tag canonicalTag = findById(tagId);
|
findById(tagId); // Validate tag exists
|
||||||
TagAlias alias = tagAliasRepository.findById(aliasId)
|
TagAlias alias = tagAliasRepository.findById(aliasId)
|
||||||
.orElseThrow(() -> new ResourceNotFoundException("Tag alias", aliasId.toString()));
|
.orElseThrow(() -> new ResourceNotFoundException("Tag alias", aliasId.toString()));
|
||||||
|
|
||||||
|
|||||||
@@ -958,8 +958,9 @@ public class TypesenseService {
|
|||||||
|
|
||||||
// Try to get collection info for debugging
|
// Try to get collection info for debugging
|
||||||
try {
|
try {
|
||||||
CollectionResponse collection = typesenseClient.collections(AUTHORS_COLLECTION).retrieve();
|
typesenseClient.collections(AUTHORS_COLLECTION).retrieve();
|
||||||
} catch (Exception debugException) {
|
} catch (Exception debugException) {
|
||||||
|
// Debug collection retrieval failed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use wildcard approach for fallback to handle substring search
|
// Use wildcard approach for fallback to handle substring search
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ public abstract class BaseRepositoryTest {
|
|||||||
private static final PostgreSQLContainer<?> postgres;
|
private static final PostgreSQLContainer<?> postgres;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
postgres = new PostgreSQLContainer<>("postgres:15-alpine")
|
@SuppressWarnings("resource") // Container is managed by shutdown hook
|
||||||
|
PostgreSQLContainer<?> container = new PostgreSQLContainer<>("postgres:15-alpine")
|
||||||
.withDatabaseName("storycove_test")
|
.withDatabaseName("storycove_test")
|
||||||
.withUsername("test")
|
.withUsername("test")
|
||||||
.withPassword("test");
|
.withPassword("test");
|
||||||
|
postgres = container;
|
||||||
postgres.start();
|
postgres.start();
|
||||||
|
|
||||||
// Add shutdown hook to properly close the container
|
// Add shutdown hook to properly close the container
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -23,7 +22,6 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
|
||||||
@@ -176,7 +174,7 @@ class AuthorServiceTest {
|
|||||||
when(authorRepository.existsByName("Updated Author")).thenReturn(false);
|
when(authorRepository.existsByName("Updated Author")).thenReturn(false);
|
||||||
when(authorRepository.save(any(Author.class))).thenReturn(testAuthor);
|
when(authorRepository.save(any(Author.class))).thenReturn(testAuthor);
|
||||||
|
|
||||||
Author result = authorService.update(testId, updates);
|
authorService.update(testId, updates);
|
||||||
|
|
||||||
assertEquals("Updated Author", testAuthor.getName());
|
assertEquals("Updated Author", testAuthor.getName());
|
||||||
assertEquals("Updated notes", testAuthor.getNotes());
|
assertEquals("Updated notes", testAuthor.getNotes());
|
||||||
@@ -318,7 +316,7 @@ class AuthorServiceTest {
|
|||||||
when(authorRepository.findById(testId)).thenReturn(Optional.of(testAuthor));
|
when(authorRepository.findById(testId)).thenReturn(Optional.of(testAuthor));
|
||||||
when(authorRepository.save(any(Author.class))).thenReturn(testAuthor);
|
when(authorRepository.save(any(Author.class))).thenReturn(testAuthor);
|
||||||
|
|
||||||
Author result = authorService.setRating(testId, 4);
|
authorService.setRating(testId, 4);
|
||||||
|
|
||||||
assertEquals(4, testAuthor.getAuthorRating());
|
assertEquals(4, testAuthor.getAuthorRating());
|
||||||
verify(authorRepository, times(2)).findById(testId); // Called twice: once initially, once after flush
|
verify(authorRepository, times(2)).findById(testId); // Called twice: once initially, once after flush
|
||||||
@@ -342,7 +340,7 @@ class AuthorServiceTest {
|
|||||||
when(authorRepository.findById(testId)).thenReturn(Optional.of(testAuthor));
|
when(authorRepository.findById(testId)).thenReturn(Optional.of(testAuthor));
|
||||||
when(authorRepository.save(any(Author.class))).thenReturn(testAuthor);
|
when(authorRepository.save(any(Author.class))).thenReturn(testAuthor);
|
||||||
|
|
||||||
Author result = authorService.setRating(testId, null);
|
authorService.setRating(testId, null);
|
||||||
|
|
||||||
assertNull(testAuthor.getAuthorRating());
|
assertNull(testAuthor.getAuthorRating());
|
||||||
verify(authorRepository, times(2)).findById(testId); // Called twice: once initially, once after flush
|
verify(authorRepository, times(2)).findById(testId); // Called twice: once initially, once after flush
|
||||||
|
|||||||
Reference in New Issue
Block a user