package dev.fyloz.trial.colorrecipesexplorer.repository

import dev.fyloz.trial.colorrecipesexplorer.model.NamedModel
import org.junit.jupiter.api.Test
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
import kotlin.test.*

@DataJpaTest
abstract class AbstractNamedJpaRepositoryTest<E : NamedModel, R : NamedJpaRepository<E>>(protected val repository: R, protected val entityManager: TestEntityManager) {
    protected abstract fun entity(name: String = "entity"): E

    @Test
    fun `existsByName() returns true when an entity with the given name exists`() {
        val entity = entity()
        entityManager.persist(entity)

        val found = repository.existsByName(entity.name)

        assertTrue(found)
    }

    @Test
    fun `existsByName() returns false when no entity with the given name exist`() {
        val entity = entity()
        val anotherEntity = entity("another entity")
        entityManager.persist(anotherEntity)

        val found = repository.existsByName(entity.name)

        assertFalse(found)
    }

    @Test
    fun `findByName() returns the entity with the given name`() {
        val entity = entity()
        entityManager.persist(entity)

        val found = repository.findByName(entity.name)

        assertNotNull(found)
        assertEquals(entity.name, found.name)
    }

    @Test
    fun `findByName() returns null when no entity with the given name exists`() {
        val entity = entity()
        val anotherEntity = entity("another entity")
        entityManager.persist(anotherEntity)

        val found = repository.findByName(entity.name)

        assertNull(found)
    }

    @Test
    fun `deleteByName() removes the entity with the given name`() {
        val entity = entity()
        entityManager.persist(entity)

        repository.deleteByName(entity.name)

        assertFalse(repository.existsByName(entity.name))
    }
}
