Skip to content

refactor: migrate validations from services to controllers#183

Merged
nanotaboada merged 1 commit intomasterfrom
feature/validation
Apr 19, 2025
Merged

refactor: migrate validations from services to controllers#183
nanotaboada merged 1 commit intomasterfrom
feature/validation

Conversation

@nanotaboada
Copy link
Copy Markdown
Owner

@nanotaboada nanotaboada commented Apr 19, 2025

This change is Reviewable

Summary by CodeRabbit

  • Refactor
    • Simplified and unified response handling in the books API, with improved validation and clearer HTTP status codes.
    • Updated and streamlined service logic for creating, updating, and deleting books by removing redundant validation steps.
    • Improved naming consistency and clarity in test utility classes and test methods.
  • Bug Fixes
    • Corrected API documentation and summaries to accurately reference ISBN where appropriate.
  • Tests
    • Updated tests to align with revised service logic, removed obsolete validation checks, and improved test method naming.
  • Style
    • Improved naming conventions for classes and methods in test utilities for better readability.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 19, 2025

Walkthrough

The changes refactor the book management API and its supporting layers to streamline validation, response handling, and testing. Controller methods now rely on validation annotations and simplified service calls, returning more appropriate HTTP statuses and headers. The service layer removes manual validation logic, focusing on repository existence checks and CRUD operations. Supporting test utilities are renamed for clarity, and all tests are updated to use the new method and class names. Test logic is revised to align with the updated service and controller flows, removing validation mocks and focusing on repository interactions and response codes. Editor settings are also updated to disable Java inlay hints.

Changes

File(s) Change Summary
.vscode/settings.json Added a setting to disable Java inlay hints in the editor configuration.
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java Refactored controller methods to use validation annotations, simplified service calls, updated response handling, and improved API documentation summaries. Changed response types to ResponseEntity<Void> where appropriate.
src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java Removed Validator dependency and all validation logic. Simplified control flow in CRUD methods to focus on repository existence checks and direct returns.
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookDTOFakes.java Renamed class from BookDTOsBuilder to BookDTOFakes and updated static method names to use create instead of build.
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java Renamed class from BooksBuilder to BookFakes and updated static method names to use create instead of build.
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java Updated tests to use new test data builders, revised service method mocking and verification to match refactored service/controller logic, and updated test method names for clarity. Removed validation-related test logic.
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java Updated to use BookFakes for test data and standardized method names for ISBN capitalization.
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java Removed validation mocks and logic, updated to use new test data builders, revised test method names, and focused tests on repository interactions and mapping. Removed or merged tests that previously checked validation logic.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant BooksController
    participant BooksService
    participant BooksRepository

    Client->>BooksController: POST /books (BookDTO)
    BooksController->>BooksService: create(BookDTO)
    BooksService->>BooksRepository: existsById(isbn)
    alt Book exists
        BooksService-->>BooksController: false
        BooksController-->>Client: 409 Conflict
    else Book does not exist
        BooksService->>BooksRepository: save(Book)
        BooksService-->>BooksController: true
        BooksController-->>Client: 201 Created (Location header)
    end

    Client->>BooksController: PUT /books (BookDTO)
    BooksController->>BooksService: update(BookDTO)
    BooksService->>BooksRepository: existsById(isbn)
    alt Book exists
        BooksService->>BooksRepository: save(Book)
        BooksService-->>BooksController: true
        BooksController-->>Client: 204 No Content
    else Book does not exist
        BooksService-->>BooksController: false
        BooksController-->>Client: 404 Not Found
    end

    Client->>BooksController: DELETE /books/{isbn}
    BooksController->>BooksService: delete(isbn)
    BooksService->>BooksRepository: existsById(isbn)
    alt Book exists
        BooksService->>BooksRepository: deleteById(isbn)
        BooksService-->>BooksController: true
        BooksController-->>Client: 204 No Content
    else Book does not exist
        BooksService-->>BooksController: false
        BooksController-->>Client: 404 Not Found
    end

    Client->>BooksController: GET /books/{isbn}
    BooksController->>BooksService: retrieveByIsbn(isbn)
    BooksService->>BooksRepository: findById(isbn)
    alt Book found
        BooksService-->>BooksController: BookDTO
        BooksController-->>Client: 200 OK (BookDTO)
    else Book not found
        BooksService-->>BooksController: null
        BooksController-->>Client: 404 Not Found
    end

    Client->>BooksController: GET /books
    BooksController->>BooksService: retrieveAll()
    BooksService->>BooksRepository: findAll()
    BooksService-->>BooksController: List<BookDTO>
    BooksController-->>Client: 200 OK (List<BookDTO>)
Loading

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9202e5f and 2b44db7.

⛔ Files ignored due to path filters (1)
  • assets/images/structure.svg is excluded by !**/*.svg
📒 Files selected for processing (8)
  • .vscode/settings.json (1 hunks)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java (7 hunks)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java (4 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookDTOFakes.java (3 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java (3 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java (9 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (3 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java (6 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .vscode/settings.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.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/BookDTOFakes.java
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java
🧰 Additional context used
🧬 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/BookDTOFakes.java (1)
  • BookDTOFakes (9-157)
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)
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)
🪛 GitHub Check: Codeac Code Quality
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java

[failure] 49-61: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsTrue_thenRepositoryNeverSaveBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 64-80: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsFalse_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 75-83: CodeDuplication
This block of 8 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java:164


[warning] 56-68: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java:179


[warning] 164-172: CodeDuplication
This block of 8 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java:75


[failure] 152-169: MethodNamingConventions
The JUnit 5 test method name 'givenUpdate_whenRepositoryExistsByIdReturnsTrue_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 193-205: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenRepositoryExistsByIdReturnsFalse_thenRepositoryNeverDeleteBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'

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

[warning] 244-256: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:221


[warning] 221-233: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:244


[failure] 285-303: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidAndExistingISBN_thenResponseStatusIsNoContent' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 306-324: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidButNonExistentISBN_thenResponseStatusIsNotFound' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 314-324: CodeDuplication
This block of 10 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:293


[warning] 293-303: CodeDuplication
This block of 10 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:314

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

[failure] 25-34: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNAlreadyExists_thenShouldReturnExistingBook' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 37-44: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNDoesNotExist_thenShouldReturnEmptyOptional' doesn't match '[a-z][a-zA-Z0-9]*'

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (26)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (3)

15-15: Appropriately updated test dependency import.

The import has been updated from BooksBuilder to BookFakes, aligning with the project-wide refactoring of test utility classes to follow a more descriptive naming convention.


25-34: Method name capitalization improvement.

The test method name has been updated to consistently capitalize "ISBN" throughout the codebase, improving naming consistency. The test data creation has also been updated to use the new BookFakes.createOneValid() method instead of the former builder pattern.

Note that the static analysis tool flags the method naming convention as not matching [a-z][a-zA-Z0-9]*, but this is a false positive since the project is clearly using a given-when-then BDD-style naming convention, which is a common practice in test code.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 25-34: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNAlreadyExists_thenShouldReturnExistingBook' doesn't match '[a-z][a-zA-Z0-9]*'


37-44: Consistent naming pattern applied.

Similar to the previous test method, this one has been updated to consistently capitalize "ISBN" in the method name, improving readability and consistency across the test suite.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 37-44: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNDoesNotExist_thenShouldReturnEmptyOptional' doesn't match '[a-z][a-zA-Z0-9]*'

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

26-27: Updated utility class imports.

The imports have been properly updated to reference the renamed utility classes BookDTOFakes and BookFakes, which are part of the broader refactoring to improve naming consistency across test classes.


49-61: Refactored test to focus on repository existence check instead of validation.

This test has been correctly refactored to focus solely on repository existence checks rather than validation logic, aligning with the migration of validation responsibility from services to controllers. The test method name and assertions have been updated to reflect this change in responsibility.

The method naming convention warning from the static analysis tool is a false positive as the project is using BDD-style naming for tests.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 49-61: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsTrue_thenRepositoryNeverSaveBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


64-80: Simplified test structure with appropriate verifications.

The test has been appropriately simplified to focus on repository interactions rather than validation. The verification now checks that the model mapper is called exactly once when the repository returns false for existsById(), ensuring that the service correctly maps the DTO to a domain object before saving.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 64-80: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsFalse_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


89-105: Reorganized test assertions with improved verification order.

The test now properly verifies the repository and model mapper interactions in a logical order, with the repository check preceding the mapper verification. This reflects the execution flow of the service method being tested.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 89-105: MethodNamingConventions
The JUnit 5 test method name 'givenRetrieveByIsbn_whenRepositoryFindByIdReturnsBook_thenResultIsEqualToBook' doesn't match '[a-z][a-zA-Z0-9]*'


108-120: Added explicit model mapper verification.

The test now includes an explicit verification that the model mapper is never called when the repository returns an empty optional, ensuring that no unnecessary mapping operations are performed when no entity is found.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 108-120: MethodNamingConventions
The JUnit 5 test method name 'givenRetrieveByIsbn_whenRepositoryFindByIdReturnsEmpty_thenResultIsNull' doesn't match '[a-z][a-zA-Z0-9]*'


123-143: Updated test to use new fake data generators.

The test has been updated to use the new BookFakes and BookDTOFakes utility classes, making the test more readable and consistent with the rest of the codebase. The updated verification loop properly checks that each book is mapped exactly once.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 123-143: MethodNamingConventions
The JUnit 5 test method name 'givenRetrieveAll_whenRepositoryFindAllReturnsBooks_thenResultIsEqualToBooks' doesn't match '[a-z][a-zA-Z0-9]*'


152-169: Refactored update test with explicit model mapper verification.

The test now explicitly verifies that the model mapper is called exactly once when the book exists in the repository, ensuring that the DTO is correctly mapped to a domain object before saving.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 152-169: MethodNamingConventions
The JUnit 5 test method name 'givenUpdate_whenRepositoryExistsByIdReturnsTrue_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


172-184: Added explicit model mapper verification in negative update test.

The test now explicitly verifies that the model mapper is never called when the book doesn't exist in the repository, ensuring that no unnecessary mapping operations are performed when the update operation cannot be completed.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 172-184: MethodNamingConventions
The JUnit 5 test method name 'givenUpdate_whenRepositoryExistsByIdReturnsFalse_thenRepositoryNeverSaveBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


193-205: Added explicit model mapper verification in negative delete test.

Similar to the update test, this test now explicitly verifies that the model mapper is never called when the book doesn't exist in the repository, ensuring that no unnecessary operations are performed when the delete operation cannot be completed.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 193-205: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenRepositoryExistsByIdReturnsFalse_thenRepositoryNeverDeleteBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


208-220: Updated delete test with proper model mapper verification.

The test now correctly verifies that the model mapper is never called during a delete operation, regardless of whether the book exists in the repository or not, reflecting the fact that mapping is not needed for deletion.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 208-220: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenRepositoryExistsByIdReturnsTrue_thenRepositoryDeleteBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'

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

6-6: Added important Mockito verification import.

The import for Mockito.never() has been added, enabling verification that certain methods are not called under specific conditions. This is essential for testing that invalid data never reaches the service layer when validation is performed at the controller level.


33-33: Updated test utility class import.

The import has been correctly updated to reference the renamed utility class BookDTOFakes, which is part of the broader refactoring to improve naming consistency across test classes.


57-78: Improved POST test for existing book scenario.

The test has been updated to use the new BookDTOFakes utility and renamed variables from content to body for clarity. The test now properly verifies that the service's create method is called exactly once, even when the book already exists, reflecting that validation happens before the service call.


81-108: Enhanced test for successful book creation.

The test has been improved to properly verify the successful creation flow, including checking that the service's create method is called exactly once and verifying that the response contains the expected location header with the book's ISBN.


111-128: Added service method verification for invalid book POST.

The test now explicitly verifies that the service's create method is never called when the request body contains an invalid book, confirming that validation happens at the controller level before reaching the service.


137-159: Reordered assertions in GET by ISBN test.

The assertions have been reordered to first verify the response status and then the response body, providing a more logical flow for the test assertions. The test data creation has also been updated to use the new BookDTOFakes utility.


162-179: Improved GET test for non-existent book scenario.

The test has been updated to return null instead of a null book when mocking the service's retrieveByIsbn method for a non-existent book, better reflecting the actual service implementation.


182-204: Enhanced GET all books test with proper service method verification.

The test now properly verifies that the service's retrieveAll method is called exactly once and that the response status and body match the expected values.


213-233: Updated PUT test for existing book scenario.

The test has been updated to use the new BookDTOFakes utility and to properly verify that the service's update method is called exactly once when updating an existing book.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[warning] 221-233: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:244


236-256: Improved PUT test for non-existent book scenario.

The test has been updated to use the new BookDTOFakes utility and to properly verify that the service's update method is called exactly once when attempting to update a non-existent book, confirming that validation happens before checking for existence.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[warning] 244-256: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:221


259-276: Added service method verification for invalid book PUT.

The test now explicitly verifies that the service's update method is never called when the request body contains an invalid book, confirming that validation happens at the controller level before reaching the service.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 259-276: MethodNamingConventions
The JUnit 5 test method name 'givenPut_whenRequestBodyIsInvalidBook_thenResponseStatusIsBadRequest' doesn't match '[a-z][a-zA-Z0-9]*'


285-303: Enhanced DELETE test for existing book scenario.

The test has been updated to use the new BookDTOFakes utility and to properly verify that the service's delete method is called exactly once when deleting an existing book.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 285-303: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidAndExistingISBN_thenResponseStatusIsNoContent' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 293-303: CodeDuplication
This block of 10 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:314


306-324: Updated DELETE test for non-existent book scenario.

The test has been updated to use the new BookDTOFakes utility and to properly verify that the service's delete method is called exactly once when attempting to delete a non-existent book, confirming that validation happens before checking for existence.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 306-324: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidButNonExistentISBN_thenResponseStatusIsNotFound' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 314-324: CodeDuplication
This block of 10 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:293

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codacy-production
Copy link
Copy Markdown

codacy-production bot commented Apr 19, 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 (193d218) 56 56 100.00%
Head commit (2b44db7) 49 (-7) 49 (-7) 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 (#183) 27 27 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
Copy Markdown

codecov bot commented Apr 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (193d218) to head (2b44db7).
Report is 2 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##              master      #183   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
+ Complexity        26        20    -6     
===========================================
  Files              2         2           
  Lines             56        49    -7     
  Branches           6         4    -2     
===========================================
- Hits              56        49    -7     

☔ 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.

Copy link
Copy Markdown

@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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 193d218 and 9202e5f.

⛔ Files ignored due to path filters (1)
  • assets/images/structure.svg is excluded by !**/*.svg
📒 Files selected for processing (8)
  • .vscode/settings.json (1 hunks)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/controllers/BooksController.java (7 hunks)
  • src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java (4 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookDTOFakes.java (3 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java (3 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java (9 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (3 hunks)
  • src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java (6 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
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-152)
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-153)
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/BookDTOFakes.java (1)
  • BookDTOFakes (9-153)
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java (1)
  • BookFakes (9-152)
🪛 GitHub Check: Codeac Code Quality
src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java

[failure] 25-34: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNAlreadyExists_thenShouldReturnExistingBook' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 37-44: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNDoesNotExist_thenShouldReturnEmptyOptional' doesn't match '[a-z][a-zA-Z0-9]*'

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

[failure] 213-233: MethodNamingConventions
The JUnit 5 test method name 'givenPut_whenRequestBodyIsValidAndExistingBook_thenResponseStatusIsNoContent' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 236-256: MethodNamingConventions
The JUnit 5 test method name 'givenPut_whenRequestBodyIsValidButNonExistentBook_thenResponseStatusIsNotFound' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 244-256: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:221


[warning] 221-233: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:244


[failure] 285-303: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidAndExistingISBN_thenResponseStatusIsNoContent' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 306-324: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidButNonExistentISBN_thenResponseStatusIsNotFound' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 314-324: CodeDuplication
This block of 10 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:293


[warning] 293-303: CodeDuplication
This block of 10 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/controllers/BooksControllerTests.java:314

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

[warning] 75-83: CodeDuplication
This block of 8 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java:164


[warning] 56-68: CodeDuplication
This block of 12 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java:179


[failure] 49-61: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsTrue_thenRepositoryNeverSaveBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


[failure] 64-80: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsFalse_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


[warning] 164-172: CodeDuplication
This block of 8 lines is too similar to src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/services/BooksServiceTests.java:75


[failure] 152-169: MethodNamingConventions
The JUnit 5 test method name 'givenUpdate_whenRepositoryExistsByIdReturnsTrue_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Analyze (java-kotlin)
🔇 Additional comments (46)
.vscode/settings.json (1)

8-9: Disable Java Inlay Hints for a Cleaner Workspace

Adding "editor.inlayHints.enabled": "off" under the [java] scope silences parameter and type hints in Java files, complementing the existing default formatter ("redhat.java") and improving readability during the ongoing refactor. Since this is a workspace‑level setting, please confirm that it’s intended to be committed for the entire team rather than as a personal preference.

src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookDTOFakes.java (2)

9-9: Class name change improves clarity.

The renaming from BookDTOsBuilder to BookDTOFakes better represents the purpose of this class - to create fake DTO objects for testing, rather than using a builder pattern.


11-11: Method naming update establishes consistency.

Changing method names from buildOneValid(), buildOneInvalid(), and buildManyValid() to use the create prefix better reflects what these methods do and aligns with other test utility classes like BookFakes. This also makes the naming consistent across your test utilities.

Also applies to: 31-31, 45-45

src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/BookFakes.java (2)

9-9: Class name change clarifies intent.

Renaming from BooksBuilder to BookFakes effectively communicates the purpose of this class - providing fake Book objects for testing rather than using a builder pattern.


11-11: Method naming update establishes consistency.

Changing method names from buildOneValid(), buildOneInvalid(), and buildManyValid() to use the create prefix better reflects the actual functionality and maintains consistency with other test utilities like BookDTOFakes.

Also applies to: 31-31, 45-45

src/test/java/ar/com/nanotaboada/java/samples/spring/boot/test/repositories/BooksRepositoryTests.java (3)

15-15: Import update properly reflects class renaming.

Updated import statement correctly references the renamed BookFakes class, maintaining code functionality after the refactoring.


25-25: Method naming improvement for acronym capitalization.

The test method names now properly capitalize "ISBN" as an acronym, improving readability and consistency with naming conventions.

Also applies to: 37-37

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 25-34: MethodNamingConventions
The JUnit 5 test method name 'givenFindByIsbn_whenISBNAlreadyExists_thenShouldReturnExistingBook' doesn't match '[a-z][a-zA-Z0-9]*'


27-27: Usage of renamed factory methods.

Updated to use BookFakes.createOneValid() instead of the previous builder method, maintaining functionality while adapting to the refactored helper class.

Also applies to: 39-39

src/main/java/ar/com/nanotaboada/java/samples/spring/boot/services/BooksService.java (4)

6-7: Added Lombok annotation simplifies constructor requirements.

Adding @RequiredArgsConstructor eliminates boilerplate constructor code while ensuring that all final fields (repositories and mappers) are properly initialized.


33-35: Simplified create method logic.

Validation logic has been removed from the create method, focusing it on core business logic - checking existence and saving the entity. This supports the refactoring goal of moving validations to controllers.


71-77: Simplified update method with cleaner control flow.

The update method now uses a more straightforward if-else structure without intermediate variables, making the code more readable while maintaining the same functionality.


91-92: Simplified delete method with cleaner control flow.

The delete method has been restructured with a clearer if-else pattern that directly returns the result, making the code more concise and readable.

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

3-4: Added static import for LOCATION header constant.

This improves code readability by directly using the well-defined constant name rather than referencing through the HttpHeaders class.


8-11: Add validation annotations support.

Adding imports for validation annotations (@Valid and @ISBN) aligns with the PR objective of moving validations from services to controllers.


60-64: Improved request validation and response handling.

The method now:

  1. Uses @Valid annotation for automatic bean validation
  2. Returns a boolean result from the service layer
  3. Handles conflict case clearly with HTTP 409

This approach properly moves validation to the controller layer and simplifies the error handling flow.


65-71: Improved location header construction.

Using MvcUriComponentsBuilder.fromMethodCall() with the controller method reference is more type-safe than using string-based method names. The response construction is also more readable using the builder pattern.


81-81: Updated API documentation for accuracy.

The operation summary now correctly references ISBN instead of ID, improving API documentation clarity.


88-90: Simplified response handling with ternary operator.

The ternary operator provides a more concise way to handle the conditional response while maintaining readability.


100-100: Standardized response creation pattern.

Using ResponseEntity.status().body() pattern improves consistency with other controller methods.


110-110: Updated API documentation for accuracy.

The operation summary now correctly specifies updating by ISBN rather than a generic reference.


116-120: Streamlined update logic with validation.

The method now:

  1. Uses @Valid annotation for automatic bean validation
  2. Calls the service method directly, eliminating redundant checks
  3. Uses a ternary operator for cleaner response handling
  4. Returns the appropriate status code based on the result

This approach properly moves validation to the controller layer and simplifies the flow.


130-130: Updated API documentation for accuracy.

The operation summary now correctly references ISBN instead of ID, improving API documentation clarity.


136-140: Added validation and simplified delete logic.

The method now:

  1. Uses @ISBN annotation to validate the ISBN path variable
  2. Directly calls the service method with simplified flow
  3. Uses a ternary operator for cleaner response handling
  4. Returns the appropriate status code based on the result

This approach properly moves validation to the controller layer and simplifies the flow.

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

26-27: Test utility classes renamed for better clarity.

Changing from BookDTOsBuilder and BooksBuilder to BookDTOFakes and BookFakes better reflects the purpose of these classes - providing test fake objects rather than just building them.


49-61: Updated test to reflect validation removal from service layer.

The test now focuses on repository interactions rather than validation, specifically:

  1. The method name clearly describes the test scenario
  2. The test verifies that when a book already exists, the repository never saves it
  3. Added verification that model mapper is never called in this scenario

This aligns with the PR objective of moving validations from services to controllers.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 49-61: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsTrue_thenRepositoryNeverSaveBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


64-79: Test updated to use the new test fake factories.

The test now uses BookDTOFakes and BookFakes instead of builder classes while maintaining the same verification logic, ensuring that when a book doesn't exist, it gets properly mapped and saved to the repository.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 64-80: MethodNamingConventions
The JUnit 5 test method name 'givenCreate_whenRepositoryExistsByIdReturnsFalse_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


89-105: Test updated to use the new test fake factories.

The test now uses BookFakes and BookDTOFakes to create test objects with the same verification logic for retrieving an existing book.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 89-105: MethodNamingConventions
The JUnit 5 test method name 'givenRetrieveByIsbn_whenRepositoryFindByIdReturnsBook_thenResultIsEqualToBook' doesn't match '[a-z][a-zA-Z0-9]*'


108-119: Enhanced verification in retrieveByIsbn test.

The test now explicitly verifies that the model mapper is never called when the repository returns empty, which is an important assertion that was missing before.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 108-120: MethodNamingConventions
The JUnit 5 test method name 'givenRetrieveByIsbn_whenRepositoryFindByIdReturnsEmpty_thenResultIsNull' doesn't match '[a-z][a-zA-Z0-9]*'


123-142: Improved test for retrieveAll method.

The test now:

  1. Uses the renamed fake object factories
  2. Has a more explicit verification of the model mapper being called for each book
  3. Maintains the same overall verification logic

This refactoring maintains test coverage while using the updated test utilities.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 123-143: MethodNamingConventions
The JUnit 5 test method name 'givenRetrieveAll_whenRepositoryFindAllReturnsBooks_thenResultIsEqualToBooks' doesn't match '[a-z][a-zA-Z0-9]*'


152-169: Updated update test to focus on repository interaction.

The test now focuses on repository interactions rather than validation, verifying that when a book exists, it gets properly mapped and saved to the repository. This aligns with moving validations to the controller layer.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 152-169: MethodNamingConventions
The JUnit 5 test method name 'givenUpdate_whenRepositoryExistsByIdReturnsTrue_thenRepositorySaveBookAndResultIsTrue' doesn't match '[a-z][a-zA-Z0-9]*'


172-183: Enhanced verification in update test.

The test now explicitly verifies that the model mapper is never called when the book doesn't exist, which is an important assertion that focuses on the core service behavior without validation concerns.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 172-184: MethodNamingConventions
The JUnit 5 test method name 'givenUpdate_whenRepositoryExistsByIdReturnsFalse_thenRepositoryNeverSaveBookAndResultIsFalse' doesn't match '[a-z][a-zA-Z0-9]*'


193-204: Test refactored to focus on repository interaction.

The test now verifies that when a book doesn't exist, the delete operation is never called and the model mapper is never involved, focusing purely on the repository interaction pattern.


208-218: Test refactored for successful deletion scenario.

The test now correctly verifies that the repository's deleteById method is called when a book exists, while ensuring the model mapper is never called during a delete operation.

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

6-6: Added verification for never interactions.

Adding the static import for Mockito.never allows verifying that certain methods are never called, which is important for validating that the controller respects validation annotations before calling service methods.


33-33: Updated import for test data generation.

The import now uses BookDTOFakes instead of BookDTOsBuilder, aligning with the renamed test utility class for creating fake test data.


57-77: Updated POST test for conflict scenario.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Mocks the create method to return false (existing book)
  3. Verifies that the service method is called once
  4. Checks the response status is 409 Conflict

These changes align with the updated controller implementation.


81-107: Updated POST test for successful creation.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Mocks the create method to return true (successful creation)
  3. Verifies that the service method is called once
  4. Checks the response status is 201 Created and location header is set

These changes align with the updated controller implementation.


111-127: Updated POST test for validation failure.

The test now:

  1. Uses BookDTOFakes for creating an invalid test object
  2. Verifies that the service method is never called (validation fails before)
  3. Checks the response status is 400 Bad Request

These changes confirm that controller-level validation works properly.


137-158: Updated GET test for successful retrieval.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Properly verifies both the response status and the returned object
  3. Maintains the same core verification logic

This refactoring adapts the test to use the updated test utilities.


162-178: Updated GET test for non-existent resource.

The test now explicitly mocks the service to return null for a non-existent book and verifies the 404 Not Found response.


182-203: Updated GetAll test to use new test utilities.

The test now uses BookDTOFakes to create test data while maintaining the same verification logic.


213-232: Updated PUT test for successful update.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Mocks the update method to return true (successful update)
  3. Verifies that the service method is called once
  4. Checks the response status is 204 No Content

These changes align with the updated controller implementation.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 213-233: MethodNamingConventions
The JUnit 5 test method name 'givenPut_whenRequestBodyIsValidAndExistingBook_thenResponseStatusIsNoContent' doesn't match '[a-z][a-zA-Z0-9]*'


236-255: Updated PUT test for non-existent resource.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Mocks the update method to return false (book not found)
  3. Verifies that the service method is called once
  4. Checks the response status is 404 Not Found

These changes align with the updated controller implementation.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 236-256: MethodNamingConventions
The JUnit 5 test method name 'givenPut_whenRequestBodyIsValidButNonExistentBook_thenResponseStatusIsNotFound' doesn't match '[a-z][a-zA-Z0-9]*'


259-275: Updated PUT test for validation failure.

The test now:

  1. Uses BookDTOFakes for creating an invalid test object
  2. Verifies that the service method is never called (validation fails before)
  3. Checks the response status is 400 Bad Request

These changes confirm that controller-level validation works properly.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 259-276: MethodNamingConventions
The JUnit 5 test method name 'givenPut_whenRequestBodyIsInvalidBook_thenResponseStatusIsBadRequest' doesn't match '[a-z][a-zA-Z0-9]*'


285-302: Updated DELETE test for successful deletion.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Mocks the delete method to return true (successful deletion)
  3. Verifies that the service method is called once
  4. Checks the response status is 204 No Content

These changes align with the updated controller implementation.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 285-303: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidAndExistingISBN_thenResponseStatusIsNoContent' doesn't match '[a-z][a-zA-Z0-9]*'


306-323: Updated DELETE test for non-existent resource.

The test now:

  1. Uses BookDTOFakes for creating test data
  2. Mocks the delete method to return false (book not found)
  3. Verifies that the service method is called once
  4. Checks the response status is 404 Not Found

These changes align with the updated controller implementation.

🧰 Tools
🪛 GitHub Check: Codeac Code Quality

[failure] 306-324: MethodNamingConventions
The JUnit 5 test method name 'givenDelete_whenPathVariableIsValidButNonExistentISBN_thenResponseStatusIsNotFound' doesn't match '[a-z][a-zA-Z0-9]*'

@qlty-cloud-legacy
Copy link
Copy Markdown

Code Climate has analyzed commit 2b44db7 and detected 2 issues on this pull request.

Here's the issue category breakdown:

Category Count
Clarity 2

Note: there are 2 critical issues.

View more on Code Climate.

@sonarqubecloud
Copy link
Copy Markdown

@nanotaboada nanotaboada merged commit 6c23102 into master Apr 19, 2025
20 checks passed
@nanotaboada nanotaboada deleted the feature/validation branch April 19, 2025 19:17
@nanotaboada nanotaboada linked an issue Apr 19, 2025 that may be closed by this pull request
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.

Migrate validations from Services to Controllers layer

1 participant