mirror of
https://github.com/gotson/komga.git
synced 2026-01-07 16:33:48 +01:00
fixed a bug where books could be returned unsorted
This commit is contained in:
parent
c4f485cd25
commit
1069cb6f70
3 changed files with 124 additions and 2 deletions
|
|
@ -5,14 +5,26 @@ import org.gotson.komga.domain.model.Status
|
|||
import org.springframework.data.domain.Page
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import org.springframework.data.jpa.repository.Query
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.net.URL
|
||||
|
||||
@Repository
|
||||
interface BookRepository : JpaRepository<Book, Long> {
|
||||
@Query(
|
||||
value = "select * from Book b where b.serie_id = ?1 order by b.index",
|
||||
countQuery = "select count(*) from Book where serie_id = ?1",
|
||||
nativeQuery = true)
|
||||
fun findAllBySerieId(serieId: Long, pageable: Pageable): Page<Book>
|
||||
|
||||
@Query(
|
||||
value = "select * from Book b, Book_Metadata m where b.book_metadata_id = m.id " +
|
||||
"and b.serie_id = ?2 and m.status = ?1 order by b.index",
|
||||
countQuery = "select count(*) from Book b, Book_Metadata m where b.book_metadata_id = m.id and b.serie_id = ?2 and m.status = ?1",
|
||||
nativeQuery = true)
|
||||
fun findAllByMetadataStatusAndSerieId(status: String, serieId: Long, pageable: Pageable): Page<Book>
|
||||
|
||||
fun findByUrl(url: URL): Book?
|
||||
fun findAllByMetadataStatus(status: Status): List<Book>
|
||||
fun findAllByMetadataStatusAndSerieId(status: Status, serieId: Long, pageable: Pageable): Page<Book>
|
||||
fun findAllByMetadataThumbnailIsNull(): List<Book>
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ class SerieController(
|
|||
): Page<BookDto> {
|
||||
if (!serieRepository.existsById(id)) throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return if (readyFilter) {
|
||||
bookRepository.findAllByMetadataStatusAndSerieId(Status.READY, id, page)
|
||||
bookRepository.findAllByMetadataStatusAndSerieId(Status.READY.name, id, page)
|
||||
} else {
|
||||
bookRepository.findAllBySerieId(id, page)
|
||||
}.map { it.toDto() }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
package org.gotson.komga.interfaces.web
|
||||
|
||||
import org.gotson.komga.domain.model.BookMetadata
|
||||
import org.gotson.komga.domain.model.Status
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.domain.model.makeSerie
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.domain.persistence.SerieRepository
|
||||
import org.gotson.komga.domain.service.BookManager
|
||||
import org.gotson.komga.domain.service.LibraryManager
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.security.test.context.support.WithMockUser
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension
|
||||
import org.springframework.test.web.servlet.MockMvc
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
|
||||
import javax.persistence.EntityManager
|
||||
|
||||
@ExtendWith(SpringExtension::class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureTestDatabase
|
||||
@AutoConfigureMockMvc(printOnlyOnFailure = false)
|
||||
class SerieControllerTest(
|
||||
@Autowired private val serieRepository: SerieRepository,
|
||||
@Autowired private val bookRepository: BookRepository,
|
||||
@Autowired private val libraryManager: LibraryManager,
|
||||
@Autowired private val bookManager: BookManager,
|
||||
@Autowired private val entityManager: EntityManager,
|
||||
@Autowired private val mockMvc: MockMvc
|
||||
|
||||
) {
|
||||
|
||||
@AfterEach
|
||||
fun `clear repositories`() {
|
||||
entityManager.clear()
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun `given books with unordered index when requesting via api then books are ordered`() {
|
||||
val serie = makeSerie(
|
||||
name = "serie",
|
||||
books = listOf(makeBook("1"), makeBook("3"))
|
||||
)
|
||||
serieRepository.save(serie)
|
||||
|
||||
serie.books = serie.books.toMutableList().also { it.add(makeBook("2")) }
|
||||
serieRepository.save(serie)
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/series/${serie.id}/books?readyonly=false"))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk)
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[0].name", equalTo("1")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[1].name", equalTo("2")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[2].name", equalTo("3")))
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun `given many books with unordered index when requesting via api then books are ordered and paged`() {
|
||||
val serie = makeSerie(
|
||||
name = "serie",
|
||||
books = (1..100 step 2).map { makeBook("$it") }
|
||||
)
|
||||
serieRepository.save(serie)
|
||||
|
||||
serie.books = serie.books.toMutableList().also { it.add(makeBook("2")) }
|
||||
serieRepository.save(serie)
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/series/${serie.id}/books?readyonly=false"))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk)
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[0].name", equalTo("1")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[1].name", equalTo("2")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[2].name", equalTo("3")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[3].name", equalTo("5")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.size", equalTo(20)))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.first", equalTo(true)))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.number", equalTo(0)))
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
fun `given many books in ready state with unordered index when requesting via api then books are ordered and paged`() {
|
||||
val serie = makeSerie(
|
||||
name = "serie",
|
||||
books = (1..100 step 2).map { makeBook("$it") }
|
||||
)
|
||||
serieRepository.save(serie)
|
||||
|
||||
serie.books = serie.books.toMutableList().also { it.add(makeBook("2")) }
|
||||
serie.books.forEach { it.metadata = BookMetadata(Status.READY) }
|
||||
serieRepository.save(serie)
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/series/${serie.id}/books?readyonly=true"))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk)
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[0].name", equalTo("1")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[1].name", equalTo("2")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[2].name", equalTo("3")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.content[3].name", equalTo("5")))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.size", equalTo(20)))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.first", equalTo(true)))
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.number", equalTo(0)))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue