Skip to content

Conversation

Copy link

Copilot AI commented Nov 27, 2025

Implements search functionality allowing users to find books by keyword matching against descriptions.

Changes

Repository

  • Added findByDescriptionContainingIgnoreCase with JPQL query using parameterized binding
  • Used CAST(b.description AS string) to handle CLOB field in H2

Service

  • Added searchByDescription(String keyword) with entity-to-DTO mapping

Controller

  • Added GET /books/search?description={keyword} endpoint
  • @NotBlank validation on query param returns 400 for empty/missing input
  • OpenAPI annotations for Swagger docs

Usage

# Search for books mentioning "Java"
curl "http://localhost:9000/books/search?description=Java"

# Returns 400 Bad Request
curl "http://localhost:9000/books/search?description="

Tests

  • 8 new tests covering repository, service, and controller layers
Original prompt

This section details on the original issue you should resolve

<issue_title>Add new endpoint /books/search to handle search by description</issue_title>
<issue_description>### Description

Implement a new endpoint /books/search that allows users to search for books based on their description. This feature should integrate with the existing repository and handle search queries efficiently.

Acceptance Criteria

  • Implement the /books/search endpoint in the controller.
  • Modify the repository to support searching by description.
  • Validate and sanitize search input to avoid SQL injection.
  • Write tests to verify the endpoint works as expected.

Resources

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.


This change is Reviewable

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new API endpoint for searching books by description with case-insensitive keyword matching.
    • Input validation ensures the description parameter is not blank; invalid requests return HTTP 400.
    • Successful searches return matching results with HTTP 200 response.
  • Tests

    • Comprehensive test coverage added for search functionality across all layers.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

A new /books/search endpoint is added to enable case-insensitive book search by description. The implementation spans the controller layer with input validation, repository layer with a JPQL query, service layer with DTO mapping, and comprehensive test coverage across all layers.

Changes

Cohort / File(s) Change Summary
Controller Layer
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
Adds new GET /books/search endpoint method searchByDescription() with @NotBlank parameter validation and OpenAPI documentation for 200/400 responses; adds imports for NotBlank and RequestParam.
Repository Layer
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/repositories/BooksRepository.java
Adds new method findByDescriptionContainingIgnoreCase() with JPQL @Query annotation for case-insensitive description search with CLOB field casting; adds imports for @Query and @Param.
Service Layer
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java
Adds new method searchByDescription() that calls repository method, streams results, and maps to BookDTO list.
Controller Tests
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
Adds four test methods covering valid descriptions with/without matches, blank parameter validation (HTTP 400), and missing parameter handling; verifies service invocation and response structure.
Repository Tests
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
Adds two test methods: case-insensitive keyword matching with result verification and non-matching keyword returning empty list; adds List import.
Service Tests
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
Adds two unit tests verifying DTO mapping when repository returns matches and empty list handling.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Controller as BooksController
    participant Service as BooksService
    participant Repository as BooksRepository
    participant Database as Database

    Client->>Controller: GET /books/search?description=java
    activate Controller
    Note over Controller: `@NotBlank` validation
    
    alt Valid (not blank)
        Controller->>Service: searchByDescription(keyword)
        activate Service
        Service->>Repository: findByDescriptionContainingIgnoreCase(keyword)
        activate Repository
        Repository->>Database: SELECT * WHERE description LIKE (case-insensitive)
        activate Database
        Database-->>Repository: List<Book>
        deactivate Database
        deactivate Repository
        
        Service->>Service: Stream & map to List<BookDTO>
        Service-->>Controller: List<BookDTO>
        deactivate Service
        
        Controller-->>Client: HTTP 200 + JSON response
    else Blank or Missing
        Note over Controller: Validation fails
        Controller-->>Client: HTTP 400 Bad Request
    end
    deactivate Controller
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

  • JPQL query correctness: Verify the CAST and LOWER syntax for CLOB field handling in case-insensitive search
  • Validation chain: Confirm @NotBlank validation is properly enforced before service invocation
  • DTO mapping completeness: Ensure all fields are correctly mapped in the stream operation
  • Test coverage sufficiency: Validate that all HTTP status codes and edge cases (empty results, missing parameter) are covered

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding a new /books/search endpoint for description-based search functionality.
Linked Issues check ✅ Passed All acceptance criteria from issue #128 are met: endpoint implemented, repository modified with case-insensitive search, input validation applied with @notblank, and comprehensive tests added.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the /books/search endpoint as specified in issue #128; no out-of-scope modifications detected.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI changed the title [WIP] Add new endpoint /books/search for searching by description Add /books/search endpoint for description-based search Nov 27, 2025
Copilot AI requested a review from nanotaboada November 27, 2025 12:10
Copilot finished work on behalf of nanotaboada November 27, 2025 12:10
@nanotaboada
Copy link
Owner

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java (1)

69-74: Consider adding cache annotation for search results.

Other retrieval methods (retrieveByIsbn, retrieveAll) use @Cacheable to improve performance. Consider adding caching to searchByDescription to avoid redundant database queries for repeated searches.

Apply this diff to add caching:

+@Cacheable(value = "books")
 public List<BookDTO> searchByDescription(String keyword) {
     return booksRepository.findByDescriptionContainingIgnoreCase(keyword)
             .stream()
             .map(this::mapFrom)
             .toList();
 }
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (1)

57-58: Consider chaining the assertions.

The assertions can be combined into a single AssertJ chain for better readability.

Apply this diff:

-assertThat(actual).isNotEmpty();
-assertThat(actual).allMatch(book -> book.getDescription().toLowerCase().contains("java"));
+assertThat(actual)
+    .isNotEmpty()
+    .allMatch(book -> book.getDescription().toLowerCase().contains("java"));

Based on static analysis hints from SonarCloud.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cdc3194 and 14b2470.

📒 Files selected for processing (6)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java (3 hunks)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/repositories/BooksRepository.java (2 hunks)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java (1 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java (1 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (2 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Use JDK 21 (LTS) features where appropriate; do not use JDK 22+ as they cause Mockito/ByteBuddy compatibility issues
Use constructor injection with Lombok @RequiredArgsConstructor for dependency injection
Prefer Lombok annotations (@Data, @RequiredArgsConstructor, @NoArgsConstructor, @AllArgsConstructor) over manual boilerplate code
Use Java Streams API for collection processing instead of imperative loops
Package naming convention: ar.com.nanotaboada.java.samples.spring.boot.<layer>

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/repositories/BooksRepository.java
**/{controllers,services}/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/{controllers,services}/*.java: Use BookDTO for API requests/responses; Book entity is internal and should not be exposed directly
Use section dividers (e.g., /* HTTP POST */) in controllers and services

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
**/services/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Apply Spring Cache annotations (@Cacheable, @CachePut, @CacheEvict) in the service layer

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java
**/test/**/*Tests.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Name test classes with plural suffix: <ClassName>Tests (e.g., BooksControllerTests)

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
**/test/**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/test/**/*.java: Use BDD-style test method naming: given<Condition>_when<Action>_then<Expected>
Use AssertJ fluent assertions (assertThat(...).isEqualTo(...)) instead of standard JUnit assertions
Use @DisplayName for readable test descriptions in test classes
Use test data factories (BookFakes, BookDTOFakes) for consistent test data across tests
Use @MockBean for mocking Spring beans in tests and verify interactions with verify()
Test package naming convention: Insert .test before layer name (e.g., ...samples.spring.boot.test.controllers)

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
**/repositories/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Repository interfaces should extend CrudRepository<Entity, ID> from Spring Data JPA

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/repositories/BooksRepository.java
**/test/repositories/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use @DataJpaTest for repository layer tests

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
**/controllers/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Annotate REST controller methods with @Operation and @ApiResponses for OpenAPI/Swagger documentation

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
**/test/controllers/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use @WebMvcTest for controller layer tests and MockMvc for HTTP assertions

Files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/{controllers,services}/*.java : Use `BookDTO` for API requests/responses; `Book` entity is internal and should not be exposed directly
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/test/**/*.java : Use test data factories (`BookFakes`, `BookDTOFakes`) for consistent test data across tests

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/{controllers,services}/*.java : Use `BookDTO` for API requests/responses; `Book` entity is internal and should not be exposed directly

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/test/**/*Tests.java : Name test classes with plural suffix: `<ClassName>Tests` (e.g., `BooksControllerTests`)

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/test/**/*.java : Use `MockBean` for mocking Spring beans in tests and verify interactions with `verify()`

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/test/repositories/*.java : Use `DataJpaTest` for repository layer tests

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/test/**/*.java : Use AssertJ fluent assertions (`assertThat(...).isEqualTo(...)`) instead of standard JUnit assertions

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/test/controllers/*.java : Use `WebMvcTest` for controller layer tests and `MockMvc` for HTTP assertions

Applied to files:

  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/models/*DTO.java : Use Jakarta Bean Validation annotations on DTOs (`NotBlank`, `ISBN`, `URL`, etc.)

Applied to files:

  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
📚 Learning: 2025-11-25T16:16:19.398Z
Learnt from: CR
Repo: nanotaboada/java.samples.spring.boot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T16:16:19.398Z
Learning: Applies to **/repositories/*.java : Repository interfaces should extend `CrudRepository<Entity, ID>` from Spring Data JPA

Applied to files:

  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/repositories/BooksRepository.java
🧬 Code graph analysis (3)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java (2)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java (1)
  • BookFakes (9-156)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookDTOFakes.java (1)
  • BookDTOFakes (9-157)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (1)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java (1)
  • BookFakes (9-156)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java (1)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookDTOFakes.java (1)
  • BookDTOFakes (9-157)
🪛 GitHub Check: SonarCloud Code Analysis
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java

[warning] 57-57: Join these multiple assertions subject to one assertion chain.

See more on https://sonarcloud.io/project/issues?id=nanotaboada_java.samples.spring.boot&issues=AZrFNdlnSO_oWG_qfCH-&open=AZrFNdlnSO_oWG_qfCH-&pullRequest=231

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/repositories/BooksRepository.java (1)

23-31: LGTM! Secure parameterized query implementation.

The JPQL query correctly uses parameterized binding with @Param, which prevents SQL injection vulnerabilities. The CAST handles CLOB fields appropriately for H2, and the case-insensitive search implementation is well-documented.

src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java (1)

105-114: LGTM! Well-implemented search endpoint with proper validation.

The endpoint correctly applies @NotBlank validation to prevent empty searches and includes comprehensive OpenAPI documentation for 200/400 responses. The implementation properly delegates to the service layer and returns List<BookDTO>.

src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java (1)

344-434: LGTM! Comprehensive test coverage for the search endpoint.

The test suite thoroughly covers all scenarios: matching results, empty results, blank parameter validation, and missing parameter validation. Tests follow BDD naming conventions, use MockMvc correctly, verify service interactions, and employ AssertJ fluent assertions.

src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java (1)

222-264: LGTM! Thorough unit tests with proper mocking and verification.

The tests correctly verify repository calls, ModelMapper interactions for each book entity, and result mapping to DTOs. They follow BDD naming conventions and use test data factories appropriately.

@codacy-production
Copy link

codacy-production bot commented Nov 28, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.00% (target: -1.00%) 100.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (cdc3194) 49 49 100.00%
Head commit (52cb909) 55 (+6) 55 (+6) 100.00% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#231) 6 6 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

@codecov
Copy link

codecov bot commented Nov 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (cdc3194) to head (52cb909).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##              master      #231   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
- Complexity        20        22    +2     
===========================================
  Files              2         2           
  Lines             49        55    +6     
  Branches           4         4           
===========================================
+ Hits              49        55    +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nanotaboada nanotaboada force-pushed the copilot/add-books-search-endpoint branch from 14b2470 to d9b6de0 Compare December 2, 2025 21:27
- Add GET /books/search endpoint with case-insensitive description search
- Implement custom JPQL query with H2 CLOB handling in BooksRepository
- Add searchByDescription method to BooksService (no caching for dynamic results)
- Add request validation with @notblank annotation
- Add comprehensive OpenAPI documentation with detailed response descriptions
- Add 10 new unit tests across all layers (4 controller, 2 service, 4 repository)
- Add case-insensitivity test to verify LOWER() functions work correctly
- Expand BooksDataInitializer with 10 additional free programming books
- Update BookFakes test data to use unique ISBNs and avoid conflicts

Closes #128
@nanotaboada nanotaboada force-pushed the copilot/add-books-search-endpoint branch from d9b6de0 to 52cb909 Compare December 2, 2025 21:39
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 2, 2025

@nanotaboada nanotaboada marked this pull request as ready for review December 2, 2025 21:43
@nanotaboada nanotaboada merged commit 6f38258 into master Dec 2, 2025
17 checks passed
@nanotaboada nanotaboada deleted the copilot/add-books-search-endpoint branch December 2, 2025 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add new endpoint /books/search to handle search by description

2 participants