Skip to content

fix(generalOPD): replace RuntimeException with IEMRException and add unit tests#209

Open
PragyaTripathi990 wants to merge 2 commits intoPSMRI:mainfrom
PragyaTripathi990:fix/improve-exception-handling-and-add-unit-tests
Open

fix(generalOPD): replace RuntimeException with IEMRException and add unit tests#209
PragyaTripathi990 wants to merge 2 commits intoPSMRI:mainfrom
PragyaTripathi990:fix/improve-exception-handling-and-add-unit-tests

Conversation

@PragyaTripathi990
Copy link
Copy Markdown

@PragyaTripathi990 PragyaTripathi990 commented May 7, 2026

Summary

  • Added 14 unit tests for NCD Screening service covering all 6 screening methods with success and failure paths
  • Added 9 unit tests for Login service covering 4 methods
  • Replaced bare RuntimeException and generic Exception throws with domain-specific IEMRException in General OPD service

Test plan

  • Run NCDScreeningServiceImplTest — all 14 tests pass
  • Run IemrMmuLoginServiceImplTest — all 9 tests pass
  • Verify saveNurseData, saveDoctorData, updateGeneralOPDDoctorData throw IEMRException on failure instead of leaking as unhandled 500 errors

…unit tests

- Replace all bare RuntimeException/Exception throws in saveNurseData,
  saveDoctorData, and updateGeneralOPDDoctorData with descriptive IEMRException
- Update GeneralOPDService interface to explicitly declare IEMRException
- Add 14 unit tests for NCDScreeningServiceImpl (all 6 screening save methods)
- Add 9 unit tests for IemrMmuLoginServiceImpl (all 4 login methods)
- All 23 new tests pass (0 failures, 0 errors)
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

📝 Walkthrough

Walkthrough

This PR standardizes exception handling in GeneralOPD service operations by replacing generic RuntimeException/Exception throws with domain-specific IEMRException. Additionally, comprehensive test coverage is added for login service data retrieval methods and NCD screening service save operations across six screening types.

Changes

GeneralOPD Exception Handling Standardization

Layer / File(s) Summary
Interface Exception Contract
src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDService.java
Import IEMRException and update saveNurseData and saveDoctorData method signatures to declare throws IEMRException, Exception.
Implementation Error Paths
src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.java
saveNurseData, saveDoctorData, and updateGeneralOPDDoctorData methods now throw IEMRException with descriptive messages when beneficiary operations or data saves fail.

New Test Coverage for Login and NCD Screening Services

Layer / File(s) Summary
Login Service Tests
src/test/java/com/iemr/hwc/service/login/IemrMmuLoginServiceImplTest.java
JUnit 5 + Mockito test class for IemrMmuLoginServiceImpl covering four methods: getUserServicePointVanDetails, getServicepointVillages, getUserVanSpDetails, and getUserSpokeDetails with data presence and absence scenarios.
NCD Screening Service Tests
src/test/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImplTest.java
JUnit 5 + Mockito test class for NCDScreeningServiceImpl with save operation tests for six screening types (diabetes, hypertension, oral, breast, cervical, CBAC), verifying success returns and IEMRException on repository failures.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 From service to screen so bright,
Exceptions now caught just right,
Tests multiply like spring carrots,
Coverage flows through all the merits,
Error handling hops with delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: replacing RuntimeException with IEMRException in generalOPD service and adding unit tests, which matches the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

🧹 Nitpick comments (2)
src/test/java/com/iemr/hwc/service/login/IemrMmuLoginServiceImplTest.java (1)

91-97: ⚡ Quick win

Prefer structural JSON assertions over String.contains(...) checks.

These checks are fragile; parsing the response and asserting key presence/value types will make tests more reliable against formatting/noise changes while still validating behavior.

Also applies to: 123-127, 152-157, 180-185

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/com/iemr/hwc/service/login/IemrMmuLoginServiceImplTest.java`
around lines 91 - 97, The test uses fragile String.contains assertions for the
response from getUserServicePointVanDetails; instead parse the result into a
JSON object (e.g., Jackson ObjectMapper -> JsonNode) and replace the
assertTrue(result.contains(...)) checks with structural assertions such as
node.has("userVanDetails"), node.has("userSpDetails"),
node.has("parkingPlaceLocationList") and, where appropriate, assert the expected
node types (array/object) or values; apply the same change pattern to the other
similar assertions mentioned (the blocks around lines 123-127, 152-157, 180-185)
in IemrMmuLoginServiceImplTest so tests validate JSON structure rather than
string formatting.
src/test/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImplTest.java (1)

173-247: ⚡ Quick win

Add missing null id failure-path tests for remaining save methods.

Line 173 onward covers repo returns null for oral/breast/cervical/cbac, but not the save() returns entity with null id` scenario that you already test for diabetes/hypertension. Add that case for parity and regression protection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImplTest.java`
around lines 173 - 247, Add tests that cover the "repo returns entity with null
id" failure path for saveOralCancerDetails, saveBreastCancerDetails,
saveCervicalDetails and saveCbacDetails (similar to the diabetes/hypertension
null-id tests). For each method, mock the corresponding repo
(oralCancerScreeningRepo, breastCancerScreeningRepo,
cervicalCancerScreeningRepo, cbacDetailsRepo) to return the entity instance
whose getId() returns null, then assertThrows(IEMRException.class, () ->
ncdScreeningService.saveXxxDetails(...)) and verify the exception message
matches the existing failure messages ("Error while saving oral screening",
"Error while saving breast cancer screening", "Error while saving cervical
screening", "Error while saving Cbac details"). Ensure you add one test per save
method using the same naming pattern as the other tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.java`:
- Line 814: The null-input branch in saveDoctorData currently returns a null
saveSuccessFlag; instead throw new IEMRException("Invalid input") when
requestOBJ == null to honor the declared exception contract and keep behavior
deterministic; update the similar null-input branch later in the file (the
corresponding doctor save/update method around the second occurrence) to throw
the same IEMRException rather than returning null so both code paths
consistently signal invalid input.
- Line 1450: The method updateGeneralOPDDoctorData currently returns a null
updateSuccessFlag when requestOBJ is null; instead detect a missing/null
requestOBJ at the top of updateGeneralOPDDoctorData and throw an IEMRException
with a clear message (e.g., "Missing doctor update input") rather than returning
null; apply the same change to the other update method in this class that
follows the same pattern (the later update method that also returns
updateSuccessFlag) so any null requestOBJ consistently raises IEMRException.

---

Nitpick comments:
In `@src/test/java/com/iemr/hwc/service/login/IemrMmuLoginServiceImplTest.java`:
- Around line 91-97: The test uses fragile String.contains assertions for the
response from getUserServicePointVanDetails; instead parse the result into a
JSON object (e.g., Jackson ObjectMapper -> JsonNode) and replace the
assertTrue(result.contains(...)) checks with structural assertions such as
node.has("userVanDetails"), node.has("userSpDetails"),
node.has("parkingPlaceLocationList") and, where appropriate, assert the expected
node types (array/object) or values; apply the same change pattern to the other
similar assertions mentioned (the blocks around lines 123-127, 152-157, 180-185)
in IemrMmuLoginServiceImplTest so tests validate JSON structure rather than
string formatting.

In
`@src/test/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImplTest.java`:
- Around line 173-247: Add tests that cover the "repo returns entity with null
id" failure path for saveOralCancerDetails, saveBreastCancerDetails,
saveCervicalDetails and saveCbacDetails (similar to the diabetes/hypertension
null-id tests). For each method, mock the corresponding repo
(oralCancerScreeningRepo, breastCancerScreeningRepo,
cervicalCancerScreeningRepo, cbacDetailsRepo) to return the entity instance
whose getId() returns null, then assertThrows(IEMRException.class, () ->
ncdScreeningService.saveXxxDetails(...)) and verify the exception message
matches the existing failure messages ("Error while saving oral screening",
"Error while saving breast cancer screening", "Error while saving cervical
screening", "Error while saving Cbac details"). Ensure you add one test per save
method using the same naming pattern as the other tests.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5120f863-bbaf-462c-925f-7cb655fb54de

📥 Commits

Reviewing files that changed from the base of the PR and between 3861dd1 and 652e055.

📒 Files selected for processing (4)
  • src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDService.java
  • src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.java
  • src/test/java/com/iemr/hwc/service/login/IemrMmuLoginServiceImplTest.java
  • src/test/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImplTest.java

@Override
@Transactional(rollbackFor = Exception.class)
public Long saveDoctorData(JsonObject requestOBJ, String Authorization) throws Exception {
public Long saveDoctorData(JsonObject requestOBJ, String Authorization) throws IEMRException, Exception {
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 | 🟠 Major | ⚡ Quick win

Do not silently return null when doctor save input is missing.

Line 814 introduces explicit IEMRException, but the requestOBJ == null path still returns saveSuccessFlag as null. Throw an IEMRException("Invalid input") there to keep contract behavior deterministic.

Suggested fix
-		} else {
-			// request OBJ is null.
-		}
+		} else {
+			throw new IEMRException("Invalid input");
+		}
 		return saveSuccessFlag;

Also applies to: 1010-1013

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.java` at
line 814, The null-input branch in saveDoctorData currently returns a null
saveSuccessFlag; instead throw new IEMRException("Invalid input") when
requestOBJ == null to honor the declared exception contract and keep behavior
deterministic; update the similar null-input branch later in the file (the
corresponding doctor save/update method around the second occurrence) to throw
the same IEMRException rather than returning null so both code paths
consistently signal invalid input.

// update doctor data
@Transactional(rollbackFor = Exception.class)
public Long updateGeneralOPDDoctorData(JsonObject requestOBJ, String Authorization) throws Exception {
public Long updateGeneralOPDDoctorData(JsonObject requestOBJ, String Authorization) throws IEMRException, Exception {
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 | 🟠 Major | ⚡ Quick win

Do not silently return null when doctor update input is missing.

Line 1450 follows the same pattern: null requestOBJ falls through and returns updateSuccessFlag as null. This should raise IEMRException to match the standardized exception handling in this PR.

Suggested fix
-		} else {
-			// request OBJ is null.
-		}
+		} else {
+			throw new IEMRException("Invalid input");
+		}
 		return updateSuccessFlag;

Also applies to: 1660-1663

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.java` at
line 1450, The method updateGeneralOPDDoctorData currently returns a null
updateSuccessFlag when requestOBJ is null; instead detect a missing/null
requestOBJ at the top of updateGeneralOPDDoctorData and throw an IEMRException
with a clear message (e.g., "Missing doctor update input") rather than returning
null; apply the same change to the other update method in this class that
follows the same pattern (the later update method that also returns
updateSuccessFlag) so any null requestOBJ consistently raises IEMRException.

IEMRException extends Exception so declaring both is a SonarQube code smell.
Revert interface/impl throws clauses to Exception while keeping IEMRException
as the thrown type in the method bodies for specificity.
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 7, 2026

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