Skip to content

test: add unit tests for MedicalRecord entity and response DTOs #139

Merged
annikaholmqvist94 merged 3 commits intomainfrom
feat/medical-record-entity-dtos-test
Apr 7, 2026
Merged

test: add unit tests for MedicalRecord entity and response DTOs #139
annikaholmqvist94 merged 3 commits intomainfrom
feat/medical-record-entity-dtos-test

Conversation

@annikaholmqvist94
Copy link
Copy Markdown
Contributor

@annikaholmqvist94 annikaholmqvist94 commented Apr 7, 2026

Summary

  • Lägger till enhetstester för MedicalRecord-entiteten som täcker getters/setters, status- och closedAt-logik, attachment-hantering (add/remove/setAll, oföränderlig lista, null-skydd)
    samt lifecycle-hookarna onCreate/onUpdate.
  • Lägger till enhetstester för MedicalRecordResponse.from(...) och MedicalRecordSummaryResponse.from(...) med happy paths, null-hantering av assignedVet samt sad paths för
    obligatoriska relationer (pet, owner, clinic, createdBy).
  • Följer samma struktur och konventioner som befintliga Comment-tester (AssertJ, reflection-helpers för att sätta id:n och trigga @PrePersist).

Summary by CodeRabbit

  • Tests
    • Expanded test coverage for medical record data transformation and entity behavior validation.

- Created `MedicalRecordEntityTest` to provide comprehensive test coverage for `MedicalRecord`.
- Included tests for getters, setters, status logic, attachments handling, and lifecycle methods (`onCreate`, `onUpdate`).
- Introduced `MedicalRecordSummaryResponseTest` to validate mapping logic for all fields.
- Added tests for both happy paths (e.g., correct mapping, null handling) and sad paths (e.g., `NullPointerException` for required fields).

Closes #99
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

This PR introduces three comprehensive JUnit 5 test classes for the medical record domain: MedicalRecordEntityTest validates entity behavior (fields, associations, lifecycle methods, status transitions), while MedicalRecordResponseTest and MedicalRecordSummaryResponseTest verify DTO mapping correctness and null handling.

Changes

Cohort / File(s) Summary
Medical Record Entity Tests
src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java
Comprehensive tests for getter/setter behavior, association management, attachment handling with back-reference linking, status/closure logic (OPEN/CLOSED transitions, closedAt preservation), and lifecycle methods (onCreate/onUpdate timestamp initialization). Includes negative path testing for default null values.
Medical Record Response DTO Tests
src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java, src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordSummaryResponseTest.java
Tests for DTO mapping from MedicalRecord entities, verifying field projection (IDs, names, status, timestamps), conditional closedAt handling when status is CLOSED, null propagation for assignedVet, and NullPointerException assertions when critical associations (pet, owner, clinic, createdBy) are null. Uses reflection for private field access and protected method invocation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

test

Suggested reviewers

  • johanbriger
  • TatjanaTrajkovic

Poem

🐰 Hopping through tests with glee,
Entity fields now verified to be,
DTOs mapped with care so true,
Null paths caught—the suite shines through!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'test: add unit tests for MedicalRecord entity and response DTOs' clearly summarizes the main change: adding test coverage for the MedicalRecord entity and its response DTO classes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/medical-record-entity-dtos-test

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

🧹 Nitpick comments (2)
src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java (1)

220-238: Strengthen onUpdate assertion and remove overlapping test intent.

onUpdate_shouldRefreshUpdatedAtWithoutModifyingCreatedAt currently verifies non-null + stable createdAt, but not that updatedAt actually moves forward. Also, Line 231-238 overlaps this behavior.

♻️ Proposed consolidation
 `@Test`
 void onUpdate_shouldRefreshUpdatedAtWithoutModifyingCreatedAt() {
     record.onCreate();
     Instant createdAt = record.getCreatedAt();
+    Instant previousUpdatedAt = record.getUpdatedAt();

     record.onUpdate();

-    assertThat(record.getUpdatedAt()).isNotNull();
     assertThat(record.getCreatedAt()).isEqualTo(createdAt);
+    assertThat(record.getUpdatedAt()).isNotNull();
+    assertThat(record.getUpdatedAt()).isAfterOrEqualTo(previousUpdatedAt);
 }
-
-@Test
-void onUpdate_shouldNotModifyCreatedAt() {
-    record.onCreate();
-    Instant originalCreatedAt = record.getCreatedAt();
-
-    record.onUpdate();
-
-    assertThat(record.getCreatedAt()).isEqualTo(originalCreatedAt);
-}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java`
around lines 220 - 238, The two tests overlap: consolidate into a single test
(e.g., onUpdate_shouldRefreshUpdatedAtWithoutModifyingCreatedAt) that calls
record.onCreate(), captures Instant originalCreatedAt = record.getCreatedAt(),
waits or ensures time advances if needed, calls record.onUpdate(), then
assertThat(record.getUpdatedAt()).isAfter(originalCreatedAt) and
assertThat(record.getCreatedAt()).isEqualTo(originalCreatedAt); remove the
redundant onUpdate_shouldNotModifyCreatedAt test so you only verify both that
updatedAt advanced and createdAt stayed the same (use record.onCreate(),
record.onUpdate(), record.getCreatedAt(), record.getUpdatedAt()).
src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java (1)

163-173: Consider extracting reflection helpers into a shared test utility.

setPrivateField / callProtectedMethod are duplicated here and in src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordSummaryResponseTest.java (Line 112-122). A small shared helper would reduce duplication.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java`
around lines 163 - 173, Extract the duplicated reflection helpers into a single
test utility class (e.g., ReflectTestUtils) exposing static methods
setPrivateField(Object target, String fieldName, Object value) and
callProtectedMethod(Object target, String methodName) that perform the same
reflection steps and rethrow or wrap checked exceptions as RuntimeException;
then replace the local private methods in MedicalRecordResponseTest and
MedicalRecordSummaryResponseTest with calls to
ReflectTestUtils.setPrivateField(...) and
ReflectTestUtils.callProtectedMethod(...). Ensure the utility class is in a test
sources package accessible to both tests and that method signatures and behavior
match the originals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java`:
- Around line 108-115: The test from_shouldMapClosedAtWhenStatusIsClosed can
pass falsely when both closedAt values are null; update the test in
MedicalRecordResponseTest so it ensures a non-null closedAt is mapped by either
(a) set a concrete closedAt on the source record before calling
MedicalRecordResponse.from(record) (e.g., record.setClosedAt(...)) or (b) add an
assertion that response.closedAt() is not null and then
assertThat(response.closedAt()).isEqualTo(record.getClosedAt()); reference the
test method from_shouldMapClosedAtWhenStatusIsClosed, the factory
MedicalRecordResponse.from, and the accessors response.closedAt() and
record.getClosedAt() when making the change.

---

Nitpick comments:
In
`@src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java`:
- Around line 163-173: Extract the duplicated reflection helpers into a single
test utility class (e.g., ReflectTestUtils) exposing static methods
setPrivateField(Object target, String fieldName, Object value) and
callProtectedMethod(Object target, String methodName) that perform the same
reflection steps and rethrow or wrap checked exceptions as RuntimeException;
then replace the local private methods in MedicalRecordResponseTest and
MedicalRecordSummaryResponseTest with calls to
ReflectTestUtils.setPrivateField(...) and
ReflectTestUtils.callProtectedMethod(...). Ensure the utility class is in a test
sources package accessible to both tests and that method signatures and behavior
match the originals.

In `@src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java`:
- Around line 220-238: The two tests overlap: consolidate into a single test
(e.g., onUpdate_shouldRefreshUpdatedAtWithoutModifyingCreatedAt) that calls
record.onCreate(), captures Instant originalCreatedAt = record.getCreatedAt(),
waits or ensures time advances if needed, calls record.onUpdate(), then
assertThat(record.getUpdatedAt()).isAfter(originalCreatedAt) and
assertThat(record.getCreatedAt()).isEqualTo(originalCreatedAt); remove the
redundant onUpdate_shouldNotModifyCreatedAt test so you only verify both that
updatedAt advanced and createdAt stayed the same (use record.onCreate(),
record.onUpdate(), record.getCreatedAt(), record.getUpdatedAt()).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa540896-2624-4cbe-9da1-309204d13851

📥 Commits

Reviewing files that changed from the base of the PR and between 47c17c6 and 6cb68e2.

📒 Files selected for processing (3)
  • src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java
  • src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordSummaryResponseTest.java
  • src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java

Comment on lines +108 to +115
void from_shouldMapClosedAtWhenStatusIsClosed() {
record.setStatus(RecordStatus.CLOSED);

MedicalRecordResponse response = MedicalRecordResponse.from(record);

assertThat(response.status()).isEqualTo(RecordStatus.CLOSED);
assertThat(response.closedAt()).isEqualTo(record.getClosedAt());
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

closedAt test can pass on a false positive.

This test should also assert non-null closedAt; currently it passes if both values are null.

✅ Tighten assertion
 `@Test`
 void from_shouldMapClosedAtWhenStatusIsClosed() {
     record.setStatus(RecordStatus.CLOSED);

     MedicalRecordResponse response = MedicalRecordResponse.from(record);

     assertThat(response.status()).isEqualTo(RecordStatus.CLOSED);
+    assertThat(record.getClosedAt()).isNotNull();
+    assertThat(response.closedAt()).isNotNull();
     assertThat(response.closedAt()).isEqualTo(record.getClosedAt());
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void from_shouldMapClosedAtWhenStatusIsClosed() {
record.setStatus(RecordStatus.CLOSED);
MedicalRecordResponse response = MedicalRecordResponse.from(record);
assertThat(response.status()).isEqualTo(RecordStatus.CLOSED);
assertThat(response.closedAt()).isEqualTo(record.getClosedAt());
}
void from_shouldMapClosedAtWhenStatusIsClosed() {
record.setStatus(RecordStatus.CLOSED);
MedicalRecordResponse response = MedicalRecordResponse.from(record);
assertThat(response.status()).isEqualTo(RecordStatus.CLOSED);
assertThat(record.getClosedAt()).isNotNull();
assertThat(response.closedAt()).isNotNull();
assertThat(response.closedAt()).isEqualTo(record.getClosedAt());
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java`
around lines 108 - 115, The test from_shouldMapClosedAtWhenStatusIsClosed can
pass falsely when both closedAt values are null; update the test in
MedicalRecordResponseTest so it ensures a non-null closedAt is mapped by either
(a) set a concrete closedAt on the source record before calling
MedicalRecordResponse.from(record) (e.g., record.setClosedAt(...)) or (b) add an
assertion that response.closedAt() is not null and then
assertThat(response.closedAt()).isEqualTo(record.getClosedAt()); reference the
test method from_shouldMapClosedAtWhenStatusIsClosed, the factory
MedicalRecordResponse.from, and the accessors response.closedAt() and
record.getClosedAt() when making the change.

@annikaholmqvist94
Copy link
Copy Markdown
Contributor Author

Closes #99

@annikaholmqvist94 annikaholmqvist94 merged commit 1cf45a8 into main Apr 7, 2026
2 checks passed
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.

1 participant