Skip to content

Deansie/exercise8#217

Open
Deansie wants to merge 43 commits intofungover:mainfrom
Deansie:Deansie/exercise8
Open

Deansie/exercise8#217
Deansie wants to merge 43 commits intofungover:mainfrom
Deansie:Deansie/exercise8

Conversation

@Deansie
Copy link
Copy Markdown

@Deansie Deansie commented Nov 22, 2025

Pull Request Type

Please check the type of change your PR introduces:

  • Feature (a new feature for the project)
  • Fix (a bug fix)
  • Chore (no production code change)
  • Refactor (refactoring production code)
  • Docs (documentation changes)
  • Style (formatting only)
  • Test (adding/refactoring tests)

Description

This PR introduces the Pet Adoption Service application from scratch, based on the kappsegla/spring-boot template branch, implementing a RESTful web service with Spring Boot, JPA for MySQL, Spring Security, Thymeleaf for UI, and additional containerization and deployment features. The Jenkinsfile with the CI/CD pipeline is included in the repository commits.

Key Features

  • REST API: Endpoints for adopting, listing, retrieving, feeding, playing with, and releasing pets, using DTOs, validation, and exception handling.

  • Persistence and Patterns: Entity with JPA, Repository interface for data access, Service layer with transactions, and DTO for API responses.

  • Security: Form-based authentication with BCrypt-encoded passwords, denying public access to REST endpoints for mutations while securing the web UI; supports environment variables for secrets.

  • Web UI: Thymeleaf templates for login and index pages with interactive JavaScript for API calls.

  • Configuration and Ops: application.yml for datasource, Dockerfile for multi-stage build, docker-compose.yml for local MySQL setup, and Jenkinsfile for CI/CD pipeline integration.

  • Deployment (Extra): Jenkins pipeline (via committed Jenkinsfile) for checkout, Maven build, Kubernetes manifest generation (Deployment, Service, HPA, Ingress), Docker image build/push, and deployment to HA Kubernetes cluster with secrets for MySQL and app password.

How Has This Been Tested?

  • JUnit 5 Tests: Unit tests for REST controller (MockMvc), service, repository, and application context; integration tests for security (authenticated vs. unauthenticated access).

  • Manual Testing: Verified API endpoints via curl/Postman (e.g., POST /pets, GET /pets/{id}), UI interactions (adopt, feed, play, release via form), login functionality, and error handling (e.g., invalid inputs, non-existent pets).

  • Local and Deployed Mode: Executed locally using docker-compose for MySQL integration, incorporating fallback datasource configurations; verified deployment to Kubernetes through the Jenkins pipeline, with operational access at https://spring-pet-adoption.ekedala-services.se/ (e.g., /pets endpoint delivers JSON data, and the /login form functions with live demo credentials: petuser/petpass123).

  • For local development testing in Linux/WSL, run these commands in two separate terminal windows in your project directory:
    docker compose up
    mvn spring-boot:run
    Use these credentials on the login-screen: petuser/petpass.
    To shut down and clean up containers afterwards, run: docker compose down

Screenshots (if appropriate)

  • Login Page:
Skärmbild från 2025-11-22 08-22-18
  • Index Page (Post-Login):
Skärmbild från 2025-11-22 08-22-44

Linked issues

This PR closes issue #193

Summary by CodeRabbit

  • New Features

    • Full pet adoption & care web UI and REST API: adopt, list, view, feed, play, release pets; styled login and protected routes.
  • Chores

    • Containerization and CI/CD pipeline for build, image publish, and deploy; local database service added; Docker build contexts optimized; project POM updated.
  • Tests

    • New unit and integration tests for controllers, service, and repository; application context smoke test added.

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

kappsegla and others added 30 commits October 8, 2025 15:56
…d password from k8s secret with fallback for dev
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 22, 2025

Walkthrough

Replaces the simple Java app with a Spring Boot pet-adoption service: adds controllers (REST + web), service layer, JPA entity/repository, DTOs, security, Thymeleaf UI, MySQL config, Docker/Docker Compose, Jenkins pipeline, updated POM, and new tests; removes the old App and its tests.

Changes

Cohort / File(s) Summary
Build & Dependency
pom.xml
Replaces POM with Spring Boot parent (3.5.6), reorganizes metadata, adds Spring Boot starters, Lombok, MySQL runtime driver, and spring-boot-maven-plugin; removes many prior plugins/configs.
Container config
Dockerfile, .dockerignore, docker-compose.yml
Adds multi-stage Dockerfile (Maven builder + Temurin JRE runtime as non-root user); adds .dockerignore excluding target, *.log, .gitignore, .git; adds docker-compose.yml with a mysql service and mysql-data volume.
CI/CD & VCS
.gitignore, Jenkinsfile
Adds *.iml to .gitignore; introduces Jenkinsfile pipeline: checkout, Dockerfile check, mvn package (skip tests), generate manifests, docker build/push, and SSH-based deploy applying manifests and waiting for rollout.
Application bootstrap & config
src/main/java/org/example/Exercise2025Application.java, src/main/resources/application.yml
Adds Spring Boot application entry point and application.yml with env-driven MySQL datasource, JPA settings (ddl-auto:update, show-sql), and logging config.
Security
src/main/java/org/example/config/SecurityConfig.java
New SecurityConfig enabling method security, defines SecurityFilterChain permitting GET /pets/** and /login, requiring auth elsewhere; configures form login at /login, BCrypt PasswordEncoder, and an in-memory user using PET_SERVICE_PASSWORD or default.
Domain & persistence
src/main/java/org/example/entity/Pet.java, src/main/java/org/example/dto/PetDTO.java, src/main/java/org/example/repository/PetRepository.java, src/main/java/org/example/exception/PetNotFoundException.java
Adds Pet JPA entity with validation, hunger/happiness bounds and timestamping, PetDTO record, PetRepository extending JpaRepository<Pet,Long>, and PetNotFoundException annotated with 404 status.
Service layer
src/main/java/org/example/service/PetService.java
New PetService with adopt, listAll, get (throws PetNotFoundException), feed (clamps hunger), play (clamps happiness), release, and toDTO mapping; transactional on write operations.
Controllers
src/main/java/org/example/controller/WebController.java, src/main/java/org/example/controller/PetRestController.java
WebController serves / and /login views; PetRestController exposes REST endpoints for adopt, list, get, feed, play, and release, using validation and DTO responses.
UI templates
src/main/resources/templates/index.html, src/main/resources/templates/login.html
Adds Thymeleaf index.html (JS UI with CSRF-aware fetch wrapper) and login.html (styled login form with CSRF/error bindings).
Tests
src/test/java/...
Removes old AppTest/AppIT; adds Exercise2025ApplicationTest (context load), PetRestControllerTest (WebMvcTest with mocked service), PetRepositoryTest (DataJpaTest, no test DB replacement), and PetServiceTest (SpringBootTest transactional).
Removed
src/main/java/org/example/App.java, src/test/java/org/example/AppTest.java, src/test/java/org/example/AppIT.java
Deletes the simple App class and its tests.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Browser
    participant WebController
    participant PetRestController
    participant PetService
    participant PetRepository
    participant MySQL

    User->>Browser: GET /
    Browser->>WebController: GET /
    WebController->>Browser: index.html + CSRF

    Browser->>PetRestController: POST /pets (JSON + CSRF)
    PetRestController->>PetService: adopt(pet)
    PetService->>PetRepository: save(pet)
    PetRepository->>MySQL: INSERT
    MySQL-->>PetRepository: generated id
    PetService->>PetRestController: PetDTO
    PetRestController->>Browser: 200 OK, PetDTO
Loading
sequenceDiagram
    actor Client
    participant Browser
    participant SpringSecurity
    participant WebController

    Client->>Browser: GET /pets
    Browser->>SpringSecurity: request /pets
    SpringSecurity-->>Browser: allow (GET permitted) or redirect to /login
    Browser->>WebController: GET /login (when redirected)
    WebController->>Browser: login.html
    Browser->>SpringSecurity: POST /login (creds + CSRF)
    SpringSecurity->>SpringSecurity: Authenticate via InMemoryUserDetails (env password)
    SpringSecurity-->>Browser: Redirect /
Loading
sequenceDiagram
    actor Dev
    participant Git
    participant Jenkins
    participant Maven
    participant Docker
    participant Registry
    participant SSH
    participant Kubernetes

    Dev->>Git: Push branch
    Git->>Jenkins: Trigger
    Jenkins->>Maven: mvn -DskipTests package
    Maven-->>Jenkins: jar
    Jenkins->>Docker: docker build (multi-stage)
    Docker->>Registry: push images (tag & latest)
    Jenkins->>SSH: scp manifests
    SSH->>Kubernetes: kubectl apply & rollout wait
    Kubernetes-->>Jenkins: rollout status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Areas to focus on:
    • SecurityConfig: filter chain rules, CSRF and UI interaction, env-based password handling.
    • PetService & PetNotFoundException: transactional correctness, clamping logic, exception handling.
    • Jenkinsfile: manifest templating, image tagging/push logic, remote SSH/deploy steps.
    • Dockerfile & .dockerignore: multi-stage paths, permissions, non-root runtime user.
    • pom.xml: plugin and dependency compatibility with Spring Boot 3.5.6 and Java 25.
    • Tests: DataJpaTest configuration (AutoConfigureTestDatabase = NONE) and CI DB availability.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 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 296a592 and 7b937df.

📒 Files selected for processing (1)
  • Jenkinsfile (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Jenkinsfile

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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: 6

🧹 Nitpick comments (15)
src/main/resources/application.yml (2)

10-11: Consider environment-specific profiles for production deployment.

The ddl-auto: update setting automatically modifies the database schema, which can be risky in production (unintended schema changes, data loss). Additionally, show-sql: true exposes queries in logs, which may include sensitive data and increases log volume.

Consider creating separate profile configurations:

src/main/resources/application-prod.yml:

spring:
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

src/main/resources/application-dev.yml:

spring:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

16-18: Consider reducing logging verbosity for production.

DEBUG level logging for org.springframework.web can produce excessive log output and may expose sensitive request/response details in production environments.

Consider using INFO level for production or leverage Spring profiles:

logging:
  level:
    org.springframework.web: ${LOGGING_LEVEL:INFO}
.dockerignore (1)

1-4: LGTM!

The exclusion patterns appropriately prevent build artifacts, logs, and VCS files from bloating the Docker build context.

Consider adding these common patterns for Spring Boot projects:

*.md
*.iml
.mvn
mvnw
mvnw.cmd
docker-compose.yml (3)

1-1: Consider removing the deprecated version field.

The Compose file version field has been deprecated since Docker Compose v1.27.0 and is ignored by modern versions.

Apply this diff:

-version: '3.8'
 services:

6-8: Consider using a stronger password even for local development.

The hard-coded password "password" is very weak. While acceptable for local development in a learning environment, consider using a slightly stronger value to reinforce good habits.

Based on learnings

Example:

environment:
  MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-dev_password_123}
  MYSQL_DATABASE: pet

3-12: Consider adding a health check for improved reliability.

Adding a health check ensures the MySQL container is ready to accept connections before dependent services start.

  mysql:
    image: mysql:9.0
    container_name: pet-mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: pet
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
Jenkinsfile (3)

7-31: Consider externalizing hard-coded values to Jenkins credentials or parameters.

The environment section contains hard-coded IP addresses, repository URLs, and infrastructure paths. While functional, externalizing these to Jenkins credentials store or build parameters would improve flexibility and security.


188-209: Consider security improvements for SSH-based deployment.

The deployment uses SSH as root with StrictHostKeyChecking=no, which bypasses host key verification and operates with elevated privileges. While functional, consider:

  1. Using a dedicated service account instead of root
  2. Enabling strict host key checking with known_hosts
  3. Alternatively, using kubectl directly from Jenkins with a kubeconfig

172-176: Consider adding error handling and cleanup for Docker builds.

The Docker build uses --no-cache which ensures fresh builds but can be slow. Consider using cache for faster builds in a CI environment, and add error handling for failed builds.

stage('Build Docker Image') {
    steps {
        script {
            try {
                sh 'docker build -t ${DOCKER_IMAGE} -f Dockerfile .'
            } catch (Exception e) {
                sh 'docker system prune -f'
                throw e
            }
        }
    }
}
pom.xml (2)

16-28: Remove or populate empty metadata sections.

The POM contains empty license, developers, and SCM sections. These should either be populated with actual information or removed to keep the POM clean.

Apply this diff to remove empty sections:

     <description>exercise2025</description>
     <url/>
-    <licenses>
-        <license/>
-    </licenses>
-    <developers>
-        <developer/>
-    </developers>
-    <scm>
-        <connection/>
-        <developerConnection/>
-        <tag/>
-        <url/>
-    </scm>
     <properties>

31-31: Consider removing explicit Lombok version.

The Lombok version is explicitly set in properties (1.18.42) and also in the maven-compiler-plugin's annotationProcessorPaths (lines 89-93). Since Spring Boot parent already manages Lombok version, the explicit version in properties is redundant.

     <properties>
         <java.version>25</java.version>
-        <lombok.version>1.18.42</lombok.version>
     </properties>

Then update the annotationProcessorPaths to use the managed version:

                     <annotationProcessorPaths>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
-                            <version>1.18.42</version>
                         </path>
                     </annotationProcessorPaths>
Dockerfile (1)

1-13: Multi-stage build and non-root runtime look solid; ensure tests run in CI, not just skipped here

The Dockerfile is well-structured and follows good practices (builder stage + non-root user). Just make sure your Jenkins pipeline (or another CI step) runs the Maven test suite before building/publishing this image, since -DskipTests here would otherwise hide failing tests.

src/main/resources/templates/login.html (1)

1-143: Login template is solid; consider a small UX/accessibility tweak

The page is well-structured and wired correctly for the /login POST and CSRF handling. As a small enhancement, you might:

  • Add a logout/success message block (e.g., th:if="${param.logout}") so users see confirmation after logging out.
  • Mark the .error container with something like aria-live="polite" to help screen readers announce login errors.

These are nice-to-have improvements; the current template is already perfectly usable.

src/main/resources/templates/index.html (1)

224-239: Consider adding validation for empty ID input.

The functions getPet, feedPet, playPet, and releasePet don't validate whether the ID field is empty before making API calls. This could result in malformed requests (e.g., /pets/ instead of /pets/{id}).

Consider adding a simple check:

 function getPet() {
     const id = document.getElementById('id').value;
+    if (!id) {
+        document.getElementById('response').textContent = '⚠️ Please enter a Pet ID';
+        return;
+    }
     fetchApi('GET', `/${id}`);
 }

Apply similar validation to feedPet, playPet, and releasePet.

src/main/java/org/example/entity/Pet.java (1)

32-39: Consider using JPA lifecycle callbacks for audit timestamps.

While the current field initialization works, the best practice for JPA audit timestamps is to use lifecycle callbacks to ensure timestamps are set during persistence operations:

-    private LocalDateTime createdAt = LocalDateTime.now();
+    private LocalDateTime createdAt;
 
-    private LocalDateTime updatedAt = LocalDateTime.now();
+    private LocalDateTime updatedAt;
 
+    @PrePersist
+    public void prePersist() {
+        createdAt = LocalDateTime.now();
+        updatedAt = LocalDateTime.now();
+    }
+
     @PreUpdate
     public void preUpdate() {
         updatedAt = LocalDateTime.now();
     }

This ensures timestamps reflect actual persistence timing rather than object instantiation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8618163 and 8616bc0.

📒 Files selected for processing (25)
  • .dockerignore (1 hunks)
  • .gitignore (1 hunks)
  • Dockerfile (1 hunks)
  • Jenkinsfile (1 hunks)
  • docker-compose.yml (1 hunks)
  • pom.xml (1 hunks)
  • src/main/java/org/example/App.java (0 hunks)
  • src/main/java/org/example/Exercise2025Application.java (1 hunks)
  • src/main/java/org/example/config/SecurityConfig.java (1 hunks)
  • src/main/java/org/example/controller/PetRestController.java (1 hunks)
  • src/main/java/org/example/controller/WebController.java (1 hunks)
  • src/main/java/org/example/dto/PetDTO.java (1 hunks)
  • src/main/java/org/example/entity/Pet.java (1 hunks)
  • src/main/java/org/example/exception/PetNotFoundException.java (1 hunks)
  • src/main/java/org/example/repository/PetRepository.java (1 hunks)
  • src/main/java/org/example/service/PetService.java (1 hunks)
  • src/main/resources/application.yml (1 hunks)
  • src/main/resources/templates/index.html (1 hunks)
  • src/main/resources/templates/login.html (1 hunks)
  • src/test/java/org/example/AppIT.java (0 hunks)
  • src/test/java/org/example/AppTest.java (0 hunks)
  • src/test/java/org/example/Exercise2025ApplicationTest.java (1 hunks)
  • src/test/java/org/example/controller/PetRestControllerTest.java (1 hunks)
  • src/test/java/org/example/entity/PetRepositoryTest.java (1 hunks)
  • src/test/java/org/example/service/PetServiceTest.java (1 hunks)
💤 Files with no reviewable changes (3)
  • src/test/java/org/example/AppIT.java
  • src/test/java/org/example/AppTest.java
  • src/main/java/org/example/App.java
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.
📚 Learning: 2025-11-16T13:56:11.263Z
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.

Applied to files:

  • src/main/java/org/example/Exercise2025Application.java
  • pom.xml
  • src/test/java/org/example/Exercise2025ApplicationTest.java
📚 Learning: 2025-11-21T16:16:54.741Z
Learnt from: LolloGro
Repo: fungover/exercise2025 PR: 211
File: src/main/resources/templates/listOfBooks.html:11-12
Timestamp: 2025-11-21T16:16:54.741Z
Learning: In the repository fungover/exercise2025, the Author DTO uses NotEmpty validation on firstName and lastName fields, and BookDto uses NotNull validation on the author field. This validation architecture ensures that books always have complete author information, making null-safety checks in Thymeleaf templates unnecessary.

Applied to files:

  • pom.xml
📚 Learning: 2025-09-10T14:02:54.365Z
Learnt from: alfredbrannare
Repo: fungover/exercise2025 PR: 66
File: src/test/java/org/example/service/WarehouseTest.java:1-21
Timestamp: 2025-09-10T14:02:54.365Z
Learning: In the fungover/exercise2025 project, static mocking of LocalDateTime.now() works successfully with the existing Mockito setup without requiring mockito-inline dependency.

Applied to files:

  • src/test/java/org/example/Exercise2025ApplicationTest.java
🔇 Additional comments (19)
.gitignore (1)

3-3: LGTM!

Adding *.iml is appropriate for excluding IntelliJ IDEA module files from version control.

src/main/resources/application.yml (1)

3-5: LGTM!

Using environment variables for database credentials is a security best practice.

src/main/java/org/example/Exercise2025Application.java (1)

1-13: LGTM!

Standard Spring Boot application entry point with correct configuration.

src/test/java/org/example/Exercise2025ApplicationTest.java (1)

1-13: LGTM!

The context load test provides a baseline verification that the Spring application context starts successfully with all configured beans.

pom.xml (3)

51-56: MySQL connector version is compatible.

Verification confirms that mysql-connector-j 9.0.0 is compatible with Spring Boot 3.5.6 and MySQL 9.0. MySQL Connector/J 9.0.0 supports MySQL Server 8.0 and later, and Spring Boot 3.x is fully compatible with the Connector/J 9.x driver using the com.mysql:mysql-connector-j coordinates. No changes needed.


5-10: I need to verify whether Spring Boot 3.5.6 specifically exists and is stable. The initial search indicates 3.5.0 is the latest stable as of May 2025, but I need to check if 3.5.6 has been released since then.


Spring Boot 3.5.6 exists and is stable for production use.

Spring Boot 3.5.6 was released and is available from Maven Central on September 18, 2025. It includes ~43 bug fixes, documentation improvements, and dependency upgrades, making it suitable for production environments. The version choice is appropriate.


30-31: No action needed — Java 25 is stable and fully supported.

Java 25 was released as General Availability (GA) on September 16, 2025 and is the current Long-Term Support (LTS) release. Spring Boot 3.5.6 is documented as compatible with Java 17–25. The specified version is stable, supported by Spring Boot 3.5.6, and appropriate as the current LTS for the project.

docker-compose.yml (1)

4-4: No compatibility issues found — MySQL 9.0 is supported.

MySQL 9.0 is compatible with Connector/J 9.0.0 (which supports MySQL 8.0 and later), and Spring Boot 3.5.x supports the MySQL Connector/J 9.x driver. The configuration is sound.

src/main/java/org/example/repository/PetRepository.java (1)

1-6: Repository definition is clean and idiomatic

The PetRepository interface is minimal and correctly set up for standard CRUD via JpaRepository<Pet, Long>. No issues here.

src/main/java/org/example/dto/PetDTO.java (1)

1-7: DTO shape looks appropriate for the current API

PetDTO captures the core identity, state (hunger/happiness), and timestamps needed for the REST responses. It’s a good fit for the service and controller usage described; no changes needed right now.

src/main/java/org/example/exception/PetNotFoundException.java (1)

1-11: 404 exception mapping for missing pets is appropriate

PetNotFoundException cleanly encapsulates the not-found case with an HTTP 404 via @ResponseStatus and a helpful message including the id. This aligns well with the service and REST API behavior.

src/main/resources/templates/index.html (1)

1-243: LGTM! Well-structured UI with proper CSRF handling.

The template provides a clean, user-friendly interface with proper CSRF token integration and comprehensive pet management capabilities. The fetchApi wrapper correctly handles both JSON and text responses.

src/main/java/org/example/controller/WebController.java (1)

7-20: LGTM! Clean and straightforward MVC controller.

The controller correctly handles view routing for the index and login pages, with proper use of Spring's Model to pass attributes to the template.

src/main/java/org/example/entity/Pet.java (1)

9-30: LGTM! Well-structured entity with proper validation.

The entity definition is clean with appropriate Jakarta validation constraints and sensible defaults for hunger and happiness levels.

src/test/java/org/example/service/PetServiceTest.java (1)

14-57: LGTM! Comprehensive service layer test coverage.

The test class effectively covers all service operations including happy paths, exception scenarios, and state mutations (feed/play). The assertions correctly verify the business logic.

src/test/java/org/example/entity/PetRepositoryTest.java (1)

11-31: LGTM! Clean repository persistence tests.

The tests appropriately verify basic CRUD operations and ID generation using the DataJpaTest slice with a real database configuration.

src/test/java/org/example/controller/PetRestControllerTest.java (1)

22-73: LGTM! Thorough controller test coverage with proper mocking.

The test class effectively validates all REST endpoints with appropriate use of MockMvc and mocked service dependencies. The security filter bypass is appropriate for focused controller unit testing.

src/main/java/org/example/controller/PetRestController.java (1)

13-50: LGTM! Clean REST controller with proper validation and status codes.

The controller follows RESTful conventions with appropriate HTTP methods, validates input on the adopt endpoint, and delegates business logic to the service layer. The use of ResponseEntity ensures correct status code handling.

src/main/java/org/example/service/PetService.java (1)

13-62: LGTM! Well-designed service layer with proper transactional boundaries.

The service implementation correctly manages transactions for write operations, handles exceptions appropriately with PetNotFoundException, and implements clean business logic for pet care actions (feeding reduces hunger, playing increases happiness). The DTO mapping is complete and accurate.

Comment thread Jenkinsfile
Comment thread Jenkinsfile
Comment thread Jenkinsfile
Comment thread Jenkinsfile
Comment thread src/main/java/org/example/config/SecurityConfig.java
Comment thread src/main/resources/templates/index.html
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.

2 participants