diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt index d2536d19b..6d7e554d6 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt @@ -6,6 +6,7 @@ import org.gotson.komga.domain.model.CopyMode import org.gotson.komga.domain.model.Media import org.gotson.komga.domain.model.PathContainedInPath import org.gotson.komga.domain.model.Series +import org.gotson.komga.domain.persistence.BookMetadataRepository import org.gotson.komga.domain.persistence.BookRepository import org.gotson.komga.domain.persistence.LibraryRepository import org.gotson.komga.domain.persistence.MediaRepository @@ -36,6 +37,7 @@ class BookImporter( private val seriesLifecycle: SeriesLifecycle, private val bookRepository: BookRepository, private val mediaRepository: MediaRepository, + private val metadataRepository: BookMetadataRepository, private val readProgressRepository: ReadProgressRepository, private val readListRepository: ReadListRepository, private val taskReceiver: TaskReceiver, @@ -115,6 +117,11 @@ class BookImporter( ) } + // copy metadata + metadataRepository.findById(upgradedBookId).let { + metadataRepository.update(it.copy(bookId = importedBook.id)) + } + // copy read progress readProgressRepository.findByBookId(upgradedBookId) .map { it.copy(bookId = importedBook.id) } diff --git a/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt b/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt index 5bf44bfd7..3462a6824 100644 --- a/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt +++ b/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt @@ -20,6 +20,7 @@ import org.gotson.komga.domain.model.ReadList import org.gotson.komga.domain.model.makeBook import org.gotson.komga.domain.model.makeLibrary import org.gotson.komga.domain.model.makeSeries +import org.gotson.komga.domain.persistence.BookMetadataRepository import org.gotson.komga.domain.persistence.BookRepository import org.gotson.komga.domain.persistence.KomgaUserRepository import org.gotson.komga.domain.persistence.LibraryRepository @@ -56,6 +57,7 @@ class BookImporterTest( @Autowired private val seriesRepository: SeriesRepository, @Autowired private val seriesLifecycle: SeriesLifecycle, @Autowired private val mediaRepository: MediaRepository, + @Autowired private val metadataRepository: BookMetadataRepository, @Autowired private val userRepository: KomgaUserRepository, @Autowired private val readListRepository: ReadListRepository, @Autowired private val readListLifecycle: ReadListLifecycle, @@ -259,6 +261,68 @@ class BookImporterTest( } } + @Test + fun `given existing book with metadata when importing with upgrade then metadata is kept`() { + Jimfs.newFileSystem(Configuration.unix()).use { fs -> + // given + val sourceDir = fs.getPath("/source").createDirectory() + val sourceFile = sourceDir.resolve("source.cbz").createFile() + val destDir = fs.getPath("/library/series").createDirectories() + val existingFile = destDir.resolve("4.cbz").createFile() + + val bookToUpgrade = makeBook("2", libraryId = library.id, url = existingFile.toUri().toURL()) + val otherBooks = listOf( + makeBook("1", libraryId = library.id), + makeBook("3", libraryId = library.id), + ) + val series = makeSeries("series", url = destDir.toUri().toURL(), libraryId = library.id) + .also { series -> + seriesLifecycle.createSeries(series) + seriesLifecycle.addBooks(series, listOf(bookToUpgrade) + otherBooks) + seriesLifecycle.sortBooks(series) + } + + metadataRepository.findById(bookToUpgrade.id).let { + metadataRepository.update( + it.copy( + summary = "a summary", + number = "HS", + numberLock = true, + numberSort = 100F, + numberSortLock = true, + ) + ) + } + + // when + bookImporter.importBook(sourceFile, series, CopyMode.MOVE, upgradeBookId = bookToUpgrade.id) + + // then + val books = bookRepository.findBySeriesId(series.id).sortedBy { it.number } + assertThat(books).hasSize(3) + assertThat(books[0].id).isEqualTo(otherBooks[0].id) + assertThat(books[1].id).isEqualTo(otherBooks[1].id) + assertThat(books[2].id).isNotEqualTo(bookToUpgrade.id) + + assertThat(bookRepository.findByIdOrNull(bookToUpgrade.id)).isNull() + + val upgradedMedia = mediaRepository.findById(books[2].id) + assertThat(upgradedMedia.status).isEqualTo(Media.Status.OUTDATED) + + with(metadataRepository.findById(books[2].id)) { + assertThat(summary).isEqualTo("a summary") + assertThat(number).isEqualTo("HS") + assertThat(numberLock).isTrue + assertThat(numberSort).isEqualTo(100F) + assertThat(numberSortLock).isTrue + } + + assertThat(Files.notExists(sourceFile)).isTrue + + verify(exactly = 1) { mockTaskReceiver.analyzeBook(any()) } + } + } + @Test fun `given existing book when importing with upgrade and same name then existing book is replaced`() { Jimfs.newFileSystem(Configuration.unix()).use { fs ->