diff --git a/src/test/java/com/ankurm/sdjpa4demo/MigrationBehaviorTests.java b/src/test/java/com/ankurm/sdjpa4demo/MigrationBehaviorTests.java index a3c078f..5bb4e30 100644 --- a/src/test/java/com/ankurm/sdjpa4demo/MigrationBehaviorTests.java +++ b/src/test/java/com/ankurm/sdjpa4demo/MigrationBehaviorTests.java @@ -2,6 +2,8 @@ package com.ankurm.sdjpa4demo; import com.ankurm.sdjpa4demo.domain.Author; import com.ankurm.sdjpa4demo.domain.Book; +import com.ankurm.sdjpa4demo.domain.BookSummary; +import com.ankurm.sdjpa4demo.domain.Money; import com.ankurm.sdjpa4demo.repo.AuthorRepository; import com.ankurm.sdjpa4demo.repo.BookRepository; import org.junit.jupiter.api.Test; @@ -11,11 +13,15 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.JpaSort; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.List; +import static com.ankurm.sdjpa4demo.repo.AuthorSpecifications.byCountryDelete; +import static com.ankurm.sdjpa4demo.repo.AuthorSpecifications.hasCountry; +import static com.ankurm.sdjpa4demo.repo.AuthorSpecifications.relabelCountry; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest @@ -29,8 +35,8 @@ class MigrationBehaviorTests { private void seed() { Author a1 = authors.save(new Author("Joshua Bloch", "US")); authors.save(new Author("Anonymous", null)); - books.save(new Book("Effective Java", new BigDecimal("45.00"), a1)); - books.save(new Book("Refactoring", new BigDecimal("45.00"), a1)); + books.save(new Book("Effective Java", new Money(new BigDecimal("45.00"), "USD"), a1)); + books.save(new Book("Refactoring", new Money(new BigDecimal("45.00"), "USD"), a1)); } @Test @@ -70,7 +76,7 @@ class MigrationBehaviorTests { void nonUniqueSingleResultThrows() { seed(); assertThrows(IncorrectResultSizeDataAccessException.class, - () -> books.findByPrice(new BigDecimal("45.00"))); + () -> books.findByPriceAmount(new BigDecimal("45.00"))); } @Test @@ -78,4 +84,74 @@ class MigrationBehaviorTests { Author a = authors.save(new Author("Erich Gamma", "CH")); assertEquals("Erich_Gamma:CH", authors.badgeFor(a.getId())); } + + // --- Corner scenarios: refined Specification API (DeleteSpecification / UpdateSpecification / PredicateSpecification) --- + + @Test + void predicateSpecificationReusedAcrossReadAndDelete() { + authors.save(new Author("Grady Booch", "US")); + authors.save(new Author("Robert Martin", "US")); + authors.save(new Author("Martin Fowler", "UK")); + + assertEquals(2, authors.findAll(hasCountry("US")).size()); + + long removed = authors.delete(hasCountry("US")); + assertEquals(2, removed); + assertTrue(authors.findAll(hasCountry("US")).isEmpty()); + } + + @Test + void deleteSpecificationBulkDelete() { + authors.save(new Author("Kent Beck", "DE")); + authors.save(new Author("Erich Gamma", "CH")); + + long removed = authors.delete(byCountryDelete("DE")); + + assertEquals(1, removed); + assertTrue(authors.findByCountry("DE") == null); + } + + @Test + void updateSpecificationBulkUpdate() { + authors.save(new Author("Martin Fowler", "UK")); + authors.save(new Author("Sam Newman", "UK")); + + long updated = authors.update(relabelCountry("UK", "GB")); + + assertEquals(2, updated); + assertEquals(2, authors.findAll(hasCountry("GB")).size()); + assertTrue(authors.findAll(hasCountry("UK")).isEmpty()); + } + + @Test + void jpaSortUnsafeCaseExpressionOrdersResults() { + authors.save(new Author("Alpha Author", "DE")); + authors.save(new Author("Beta Author", "US")); + + Sort usFirst = JpaSort.unsafe(Sort.Direction.ASC, "CASE WHEN country = 'US' THEN 0 ELSE 1 END"); + List ordered = authors.findByNameStartingWith("", usFirst); + + assertEquals("US", ordered.get(0).getCountry()); + } + + // --- Corner scenarios: Money embeddable value object --- + + @Test + void embeddedValueObjectPathTraversalWorks() { + seed(); + List found = books.findByPriceAmountGreaterThanEqual(new BigDecimal("45.00")); + assertEquals(2, found.size()); + } + + @Test + void recordProjectionPopulatesFromEmbeddedPath() { + Author a = authors.save(new Author("Kathy Sierra", "US")); + books.save(new Book("Head First Java", new Money(new BigDecimal("39.99"), "USD"), a)); + + List summaries = books.findByPriceAmountLessThanEqual(new BigDecimal("40.00")); + + assertEquals(1, summaries.size()); + assertEquals("Head First Java", summaries.get(0).title()); + assertEquals(new BigDecimal("39.99"), summaries.get(0).amount()); + } }