From 4b74025279c40988affac48e15008ea9fbf18af9 Mon Sep 17 00:00:00 2001 From: Kacper Urbaniec Date: Mon, 15 Jan 2024 18:13:17 +0100 Subject: [PATCH] Working on splitting `BeePersistentTestA` & `BeePersistentTestB` into multiple test classes Added `SelectionATest`. --- .../com/beeproduced/datasource/a/Entities.kt | 27 +- .../bee/persistent/test/BeePersistentTestA.kt | 20 +- .../persistent/test/base/ManyToManyTest.kt | 1 + .../bee/persistent/test/base/OneToManyTest.kt | 1 + .../bee/persistent/test/base/OneToOneTest.kt | 1 + .../bee/persistent/test/config/ATestConfig.kt | 24 ++ .../test/{base => config}/BaseTestConfig.kt | 2 +- .../persistent/test/persist/PersistTest.kt | 2 +- .../persistent/test/select/SelectionATest.kt | 295 ++++++++++++++++++ 9 files changed, 354 insertions(+), 19 deletions(-) create mode 100644 bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/ATestConfig.kt rename bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/{base => config}/BaseTestConfig.kt (93%) create mode 100644 bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/select/SelectionATest.kt diff --git a/bee.persistent.test/datasource.a/src/main/kotlin/com/beeproduced/datasource/a/Entities.kt b/bee.persistent.test/datasource.a/src/main/kotlin/com/beeproduced/datasource/a/Entities.kt index 9c5ccb7..ea05d33 100644 --- a/bee.persistent.test/datasource.a/src/main/kotlin/com/beeproduced/datasource/a/Entities.kt +++ b/bee.persistent.test/datasource.a/src/main/kotlin/com/beeproduced/datasource/a/Entities.kt @@ -19,8 +19,8 @@ import java.util.* @Table(name = "songs") data class Song( @Id - // @GeneratedValue // TODO: persist - val id: UUID, + @GeneratedValue + val id: UUID = UUID.randomUUID(), val name: String, @Column(name = "interpret_id") val interpretId: UUID, @@ -46,8 +46,8 @@ interface SongRepository : BeeBlazeRepository @Table(name = "persons") data class Person( @Id - // @GeneratedValue // TODO: persist - val id: UUID, + @GeneratedValue + val id: UUID = UUID.randomUUID(), val firstname: String, val lastname: String, @OneToMany(fetch = FetchType.LAZY, mappedBy = "person") @@ -58,24 +58,34 @@ data class Person( val address: Address? = null ) +@BeeRepository +interface PersonRepository : BeeBlazeRepository + @Entity @Table(name = "addresses") data class Address( @Id - val id: UUID, + @GeneratedValue + val id: UUID = UUID.randomUUID(), val street: String ) +@BeeRepository +interface AddressRepository : BeeBlazeRepository + @Entity @Table(name = "companies") data class Company( @Id - // @GeneratedValue // TODO: persist - val id: UUID, + @GeneratedValue + val id: UUID = UUID.randomUUID(), @OneToMany(fetch = FetchType.LAZY, mappedBy = "company") val employees: Set? ) +@BeeRepository +interface CompanyRepository : BeeBlazeRepository + @Embeddable data class CompanyPersonId( @Column(name = "company_id") @@ -97,6 +107,9 @@ data class CompanyPerson( val person: Person?, ) +@BeeRepository +interface CompanyPersonRepository : BeeBlazeRepository + data class FooBar( val foo: String, val bar: String diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/BeePersistentTestA.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/BeePersistentTestA.kt index 7cd47b5..d2643d1 100644 --- a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/BeePersistentTestA.kt +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/BeePersistentTestA.kt @@ -56,7 +56,7 @@ class BeePersistentTestA( ) { private val transaction = TransactionTemplate(transactionManager) - @Test + /* @Test fun `empty selection`() { addSong() transaction.executeWithoutResult { @@ -67,9 +67,9 @@ class BeePersistentTestA( assertNull(song.interpret) assertNull(song.producer) } - } + } */ - @Test + /* @Test fun `full selection`() { addSong() transaction.executeWithoutResult { @@ -172,8 +172,8 @@ class BeePersistentTestA( } } - - @Test + */ + /* @Test fun `partial selection 1`() { addSong() transaction.executeWithoutResult { @@ -223,8 +223,8 @@ class BeePersistentTestA( assertNull(song.producer) } } - - @Test + */ + /* @Test fun `partial selection 2`() { addSong() transaction.executeWithoutResult { @@ -276,8 +276,8 @@ class BeePersistentTestA( assertNotNull(pEPCP) } } - - @Test + */ + /* @Test fun `partial selection 3`() { addSong() transaction.executeWithoutResult { @@ -319,7 +319,7 @@ class BeePersistentTestA( assertTrue { producer.employees.isNullOrEmpty() } } } - + */ @Test fun `test value class and converter`() { transaction.executeWithoutResult { diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/ManyToManyTest.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/ManyToManyTest.kt index a992460..81bb8e7 100644 --- a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/ManyToManyTest.kt +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/ManyToManyTest.kt @@ -1,6 +1,7 @@ package com.beeproduced.bee.persistent.test.base import com.beeproduced.bee.persistent.blaze.selection.BeeSelection +import com.beeproduced.bee.persistent.test.config.BaseTestConfig import com.beeproduced.datasource.test.dsl.BarDSL import com.beeproduced.datasource.test.dsl.FooDSL import com.beeproduced.datasource.test.manytomany.* diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToManyTest.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToManyTest.kt index 71c5ceb..0d7a7dd 100644 --- a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToManyTest.kt +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToManyTest.kt @@ -1,6 +1,7 @@ package com.beeproduced.bee.persistent.test.base import com.beeproduced.bee.persistent.blaze.selection.BeeSelection +import com.beeproduced.bee.persistent.test.config.BaseTestConfig import com.beeproduced.datasource.test.dsl.WorkCollectionDSL import com.beeproduced.datasource.test.dsl.WorkDSL import com.beeproduced.datasource.test.onetomany.* diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToOneTest.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToOneTest.kt index dc3a228..7bec9ba 100644 --- a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToOneTest.kt +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/OneToOneTest.kt @@ -1,6 +1,7 @@ package com.beeproduced.bee.persistent.test.base import com.beeproduced.bee.persistent.blaze.selection.BeeSelection +import com.beeproduced.bee.persistent.test.config.BaseTestConfig import com.beeproduced.datasource.test.dsl.RootDSL import com.beeproduced.datasource.test.onetoone.Branch import com.beeproduced.datasource.test.onetoone.BranchRepository diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/ATestConfig.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/ATestConfig.kt new file mode 100644 index 0000000..039c9d5 --- /dev/null +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/ATestConfig.kt @@ -0,0 +1,24 @@ +package com.beeproduced.bee.persistent.test.config + +import com.netflix.graphql.dgs.autoconfig.DgsAutoConfiguration +import com.netflix.graphql.dgs.subscriptions.websockets.DgsWebSocketAutoConfig +import com.netflix.graphql.dgs.webmvc.autoconfigure.DgsWebMvcAutoConfiguration +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.context.properties.EnableConfigurationProperties + +/** + * + * + * @author Kacper Urbaniec + * @version 2024-01-14 + */ +@SpringBootApplication( + scanBasePackages = ["com.beeproduced.datasource.a"], + exclude = [ + DgsAutoConfiguration::class, + DgsWebMvcAutoConfiguration::class, + DgsWebSocketAutoConfig::class, + ] +) +@EnableConfigurationProperties +class ATestConfig \ No newline at end of file diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/BaseTestConfig.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/BaseTestConfig.kt similarity index 93% rename from bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/BaseTestConfig.kt rename to bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/BaseTestConfig.kt index 6b9aca8..2b34a2b 100644 --- a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/base/BaseTestConfig.kt +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/config/BaseTestConfig.kt @@ -1,4 +1,4 @@ -package com.beeproduced.bee.persistent.test.base +package com.beeproduced.bee.persistent.test.config import com.netflix.graphql.dgs.autoconfig.DgsAutoConfiguration import com.netflix.graphql.dgs.subscriptions.websockets.DgsWebSocketAutoConfig diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/persist/PersistTest.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/persist/PersistTest.kt index 51a7d41..4cf1b99 100644 --- a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/persist/PersistTest.kt +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/persist/PersistTest.kt @@ -1,6 +1,6 @@ package com.beeproduced.bee.persistent.test.persist -import com.beeproduced.bee.persistent.test.base.BaseTestConfig +import com.beeproduced.bee.persistent.test.config.BaseTestConfig import com.beeproduced.bee.persistent.test.beePersist import com.beeproduced.datasource.test.persist.* import jakarta.persistence.EntityManager diff --git a/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/select/SelectionATest.kt b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/select/SelectionATest.kt new file mode 100644 index 0000000..94dc135 --- /dev/null +++ b/bee.persistent.test/src/test/kotlin/com/beeproduced/bee/persistent/test/select/SelectionATest.kt @@ -0,0 +1,295 @@ +package com.beeproduced.bee.persistent.test.select + +import com.beeproduced.bee.persistent.blaze.selection.BeeSelection +import com.beeproduced.bee.persistent.test.config.ATestConfig +import com.beeproduced.datasource.a.* +import com.beeproduced.datasource.a.dsl.SongDSL +import jakarta.persistence.EntityManager +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.junit.jupiter.SpringExtension +import org.springframework.transaction.PlatformTransactionManager +import org.springframework.transaction.support.TransactionTemplate +import java.util.* +import kotlin.test.assertNotNull +import kotlin.test.assertNull +import kotlin.test.assertTrue + +/** + * + * + * @author Kacper Urbaniec + * @version 2024-01-15 + */ +@ExtendWith(SpringExtension::class) +@SpringBootTest(classes = [ATestConfig::class]) +@TestPropertySource("classpath:application.properties") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class SelectionATest( + @Qualifier("aEM") + val em: EntityManager, + @Qualifier("aTM") + transactionManager: PlatformTransactionManager, + @Autowired + val songRepo: SongRepository, + @Autowired + val companyPersonRepo: CompanyPersonRepository, + @Autowired + val personRepo: PersonRepository, + @Autowired + val companyRepo: CompanyRepository, + @Autowired + val addressRepo: AddressRepository +) { + private val transaction = TransactionTemplate(transactionManager) + + @BeforeAll + fun beforeAll() = clear() + + @AfterEach + fun afterEach() = clear() + + fun clear() { + transaction.executeWithoutResult { + songRepo.cbf.delete(em, Song::class.java).executeUpdate() + companyPersonRepo.cbf.delete(em, CompanyPerson::class.java).executeUpdate() + personRepo.cbf.delete(em, Person::class.java).executeUpdate() + companyRepo.cbf.delete(em, Company::class.java).executeUpdate() + } + } + + @Test + fun `empty selection`() { + addSong() + transaction.executeWithoutResult { + val selection = BeeSelection.empty() + val songs = songRepo.select(selection) + assertTrue { songs.isNotEmpty() } + val song = songs.first() + assertNull(song.interpret) + assertNull(song.producer) + } + } + + @Test + fun `full selection`() { + addSong() + transaction.executeWithoutResult { + val selection = SongDSL.select { + this.interpret { + this.companies { + this.company { + this.employees { + this.company { } + this.person { } + } + } + this.person { + this.companies { } + this.address { } + } + } + this.address { } + } + this.producer { + this.employees { + this.company { + this.employees { } + } + this.person { + this.companies { + this.company { } + this.person { } + } + this.address { } + } + } + } + } + val song = songRepo.select(selection).firstOrNull() + assertNotNull(song) + assertSong(song, selection) + } + } + + @Test + fun `partial selection 1`() { + addSong() + transaction.executeWithoutResult { + val selection = SongDSL.select { + this.interpret { + this.companies { + this.company { + this.employees { + this.company { } + this.person { } + } + } + this.person { + this.companies { } + this.address { } + } + } + } + } + val song = songRepo.select(selection).firstOrNull() + assertNotNull(song) + assertSong(song, selection) + } + } + + @Test + fun `partial selection 2`() { + addSong() + transaction.executeWithoutResult { + val selection = SongDSL.select { + this.producer { + this.employees { + this.company { + this.employees { } + } + this.person { + this.companies { + this.company { } + this.person { } + } + this.address { } + } + } + } + } + val song = songRepo.select(selection).firstOrNull() + assertNotNull(song) + assertSong(song, selection) + } + } + + @Test + fun `partial selection 3`() { + addSong() + transaction.executeWithoutResult { + val selection = SongDSL.select { + this.interpret { + this.companies { + this.company { } + this.person { } + } + } + this.producer { } + } + val song = songRepo.select(selection).firstOrNull() + assertNotNull(song) + assertSong(song, selection) + } + } + + private fun addSong() { + transaction.executeWithoutResult { + val address1 = addressRepo.persist(Address(UUID.randomUUID(), "Street 1")) + val address2 = addressRepo.persist(Address(UUID.randomUUID(), "Street 2")) + val person1 = personRepo.persist(Person(UUID.randomUUID(), "A", "A", null, address1.id, null)) + val person2 = personRepo.persist(Person(UUID.randomUUID(), "B", "B", null, address2.id, null)) + val company = companyRepo.persist( + Company(UUID.randomUUID(), null) + ) + val company2 = companyRepo.persist( + Company(UUID.randomUUID(), null) + ) + // companyPersonRepository.persist(CompanyPerson(CompanyPersonId(company.id, person1.id), null, null)) + companyPersonRepo.persist(CompanyPerson(CompanyPersonId(company.id, person1.id), null, null)) + companyPersonRepo.persist(CompanyPerson(CompanyPersonId(company.id, person2.id), null, null)) + companyPersonRepo.persist(CompanyPerson(CompanyPersonId(company2.id, person1.id), null, null)) + songRepo.persist( + Song( + UUID.randomUUID(), + "Song", + person1.id, + null, + company.id, + null + ) + ) + } + } + + private fun assertSong(song: Song, selection: BeeSelection) { + val interpret = song.interpret + if (selection.contains(Song::interpret.name)) { + assertNotNull(interpret) + val subselect = selection.subSelect(Song::interpret.name) + if (subselect != null) + assertPerson(interpret, subselect) + } else { + assertNull(interpret) + } + val producer = song.producer + if (selection.contains(Song::producer.name)) { + assertNotNull(producer) + val subselect = selection.subSelect(Song::producer.name) + if (subselect != null) + assertCompany(producer, subselect) + } else { + assertNull(producer) + } + } + + private fun assertPerson(person: Person, selection: BeeSelection) { + val companyPersons = person.companies + if (selection.contains(Person::companies.name)) { + assertNotNull(companyPersons) + val subselect = selection.subSelect(Person::companies.name) + if (subselect != null) + for (companyPerson in companyPersons) + assertCompanyPerson(companyPerson, subselect) + } else { + assertTrue { companyPersons.isNullOrEmpty() } + } + val address = person.address + if (selection.contains(Person::address.name)) { + assertNotNull(address) + } else { + assertNull(address) + } + } + + private fun assertCompany(company: Company, selection: BeeSelection) { + val companyPersons = company.employees + if (selection.contains(Company::employees.name)) { + assertNotNull(companyPersons) + val subselect = selection.subSelect(Company::employees.name) + if (subselect != null) + for (companyPerson in companyPersons) + assertCompanyPerson(companyPerson, subselect) + } else { + assertTrue { companyPersons.isNullOrEmpty() } + } + } + + private fun assertCompanyPerson(companyPerson: CompanyPerson, selection: BeeSelection) { + val company = companyPerson.company + if (selection.contains(CompanyPerson::company.name)) { + assertNotNull(company) + val subselect = selection.subSelect(CompanyPerson::company.name) + if (subselect != null) + assertCompany(company, subselect) + } else { + assertNull(company) + } + val person = companyPerson.person + if (selection.contains(CompanyPerson::person.name)) { + assertNotNull(person) + val subselect = selection.subSelect(CompanyPerson::person.name) + if (subselect != null) + assertPerson(person, subselect) + } else { + assertNull(person) + } + } +} \ No newline at end of file