Skip to content

Commit

Permalink
Reorder setlist entries after deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
sbont committed Jul 27, 2024
1 parent 2a8f835 commit ab08c56
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package nl.stevenbontenbal.chorister.event

import nl.stevenbontenbal.chorister.model.entities.SetlistEntry
import nl.stevenbontenbal.chorister.repository.SetlistEntryRepository
import org.springframework.data.rest.core.annotation.HandleAfterDelete
import org.springframework.data.rest.core.annotation.HandleBeforeCreate
import org.springframework.data.rest.core.annotation.RepositoryEventHandler
import org.springframework.stereotype.Component
Expand All @@ -11,11 +12,19 @@ import org.springframework.stereotype.Component
class SetlistEntryEventHandler(
private val setlistEntryRepository: SetlistEntryRepository
) {

@HandleBeforeCreate
fun handleSetlistEntryCreate(setlistEntry: SetlistEntry) {
val setlist = setlistEntry.setlist
val no = setlist.entries.size + 1
setlistEntry.number = no
}

@HandleAfterDelete
fun handleSetlistEntryDelete(oldSetlistEntry: SetlistEntry) {
oldSetlistEntry.setlist.id?.let {
val laterEntries = setlistEntryRepository.findBySetlistIdAndNumberGreaterThan(it, oldSetlistEntry.number)
laterEntries.forEach { current -> current.number -- }
setlistEntryRepository.saveAll(laterEntries)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import nl.stevenbontenbal.chorister.model.entities.SetlistEntry
import nl.stevenbontenbal.chorister.model.entities.SetlistEntryId
import org.springframework.data.repository.CrudRepository
import org.springframework.data.rest.core.annotation.RepositoryRestResource
import org.springframework.data.rest.core.annotation.RestResource

@RepositoryRestResource
interface SetlistEntryRepository: CrudRepository<SetlistEntry, SetlistEntryId> {
fun findBySetlistId(setlistId: Long): Iterable<SetlistEntry>

@RestResource(exported = false)
fun findBySetlistIdAndNumberGreaterThan(id: Long, number: Int): Iterable<SetlistEntry>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import nl.stevenbontenbal.chorister.model.entities.*
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
import java.time.LocalDate
import java.util.*
import kotlin.collections.List

fun Song.Companion.create(choir: Choir): Song {
return Song(
Expand All @@ -19,14 +20,19 @@ fun Song.Companion.create(choir: Choir): Song {
)
}

fun Setlist.Companion.create(choir: Choir): Setlist {
fun Setlist.Companion.create(choir: Choir, id: Long? = null): Setlist {
return Setlist(
id = id,
choir = choir,
name = "Christmas Morning",
date = LocalDate.of(2022, 12, 25),
)
}

fun Setlist.Companion.create(choir: Choir, entityManager: TestEntityManager): Setlist {
return Setlist.create(choir).persist(entityManager)
}

fun Category.Companion.create(choir: Choir, categoryType: CategoryType): Category {
return Category(
name = "Christmas",
Expand Down Expand Up @@ -60,14 +66,18 @@ fun Invite.Companion.create(choir: Choir): Invite {
)
}

fun SetlistEntry.Companion.create(setlist: Setlist, song: Song): SetlistEntry {
fun SetlistEntry.Companion.create(setlist: Setlist, song: Song, number: Int = 1): SetlistEntry {
return SetlistEntry(
setlist = setlist,
song = song,
number = 1
number = number
)
}

fun SetlistEntry.Companion.create(setlist: Setlist, songs: List<Song>): List<SetlistEntry> {
return songs.mapIndexed { index, song -> SetlistEntry.create(setlist, song, index + 1) }
}

fun <T> T.persist(entityManager: TestEntityManager): T {
entityManager.persist(this)
return this
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package nl.stevenbontenbal.chorister.event

import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import nl.stevenbontenbal.chorister.configuration.ChoristerConfiguration
import nl.stevenbontenbal.chorister.create
import nl.stevenbontenbal.chorister.model.entities.Choir
import nl.stevenbontenbal.chorister.model.entities.Setlist
import nl.stevenbontenbal.chorister.model.entities.SetlistEntry
import nl.stevenbontenbal.chorister.model.entities.Song
import nl.stevenbontenbal.chorister.repository.SetlistEntryRepository
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.runner.RunWith
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringRunner

@RunWith(SpringRunner::class)
@ContextConfiguration(classes = [ChoristerConfiguration::class])
class SetlistEntryEventHandlerTests {
@Test
fun `when setlist empty then first entry is 1`() {
// Arrange
val choir = Choir.create()
val setlist = Setlist.create(choir, 1)
val song1 = Song.create(choir)
val entry = SetlistEntry.create(setlist, song1)
val repository: SetlistEntryRepository = mockk(relaxed = true)
val target = SetlistEntryEventHandler(repository)

// Act
target.handleSetlistEntryCreate(entry)

// Assert
Assertions.assertThat(entry.number).isEqualTo(1)
}

@Test
fun `when setlist contains 2 then next entry is 3`() {
// Arrange
val choir = Choir.create()
val setlist = Setlist.create(choir, 1)
val song1 = Song.create(choir)
val song2 = Song.create(choir)
val song3 = Song.create(choir)
val entries = SetlistEntry.create(setlist, listOf(song1, song2, song3))
setlist.entries.addAll(entries.take(2))
val repository: SetlistEntryRepository = mockk(relaxed = true)
val target = SetlistEntryEventHandler(repository)

// Act
target.handleSetlistEntryDelete(entries[2])

// Assert
Assertions.assertThat(entries[2].number).isEqualTo(3)
}

@Test
fun `when entry deleted then following entries are reordered`() {
// Arrange
val choir = Choir.create()
val setlist = Setlist.create(choir, 1)
val song1 = Song.create(choir)
val song2 = Song.create(choir)
val song3 = Song.create(choir)
val entries = SetlistEntry.create(setlist, listOf(song1, song2, song3))
val repository: SetlistEntryRepository = mockk(relaxed = true)
every { repository.findBySetlistIdAndNumberGreaterThan(setlist.id!!, 1) }.returns(listOf(entries[1], entries[2]))
val target = SetlistEntryEventHandler(repository)

// Act
target.handleSetlistEntryDelete(entries[0])

// Assert
verify(exactly = 1) { repository.saveAll(listOf(entries[1], entries[2])) }
Assertions.assertThat(entries[1].number).isEqualTo(1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class SetlistEntryRepositoryTests @Autowired constructor(
fun `When findBySetlistId then return all setlist's entries`() {
// Arrange
val choir = Choir.create().persist(entityManager)
val setlist = Setlist.create(choir).persist(entityManager)
val setlist = Setlist.create(choir, entityManager)
val song1 = Song.create(choir).persist(entityManager)
val song2 = Song.create(choir).persist(entityManager)
val song3 = Song.create(choir).persist(entityManager)
val entry1 = SetlistEntry.create(setlist, song1).persist(entityManager)
val entry2 = SetlistEntry.create(setlist, song2).persist(entityManager)
Song.create(choir).persist(entityManager)
SetlistEntry.create(setlist, song1).persist(entityManager)
SetlistEntry.create(setlist, song2).persist(entityManager)
// Act
val setlists = setlistEntryRepository.findBySetlistId(setlistId = setlist.id!!)
// Assert
Expand Down

0 comments on commit ab08c56

Please sign in to comment.