Skip to content

[ENG-88] Test cases for delivery order#3318

Merged
vigneshhari merged 24 commits into
developfrom
test/delivery_order
Jun 23, 2026
Merged

[ENG-88] Test cases for delivery order#3318
vigneshhari merged 24 commits into
developfrom
test/delivery_order

Conversation

@nandkishorr

@nandkishorr nandkishorr commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

Merge Checklist

  • Tests added/fixed
  • Update docs in /docs
  • Linting Complete
  • Any other necessary step

Only PR's with test cases included and passing lint and test pipelines will be reviewed

@ohcnetwork/care-backend-maintainers @ohcnetwork/care-backend-admins

Summary by CodeRabbit

  • Bug Fixes

    • Clarified authorization error messages for delivery order actions and changed retrieval rules so read access to at least one of the origin or destination is required.
  • Tests

    • Added extensive delivery-order tests covering create/update/retrieve/list/filters/permissions/status transitions and medication-return workflows; refactored test grouping and added price components in test setup.

@nandkishorr nandkishorr requested a review from a team as a code owner October 27, 2025 13:18
@codecov

codecov Bot commented Oct 27, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.33%. Comparing base (73af000) to head (790df82).
⚠️ Report is 4 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3318      +/-   ##
===========================================
+ Coverage    77.53%   78.33%   +0.80%     
===========================================
  Files          479      479              
  Lines        22998    22994       -4     
  Branches      2379     2378       -1     
===========================================
+ Hits         17831    18013     +182     
+ Misses        4613     4412     -201     
- Partials       554      569      +15     

☔ View full report in Codecov by Harness.
📢 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai

coderabbitai Bot commented Nov 17, 2025

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Updated delivery-order authorization to require read access to at least one of origin or destination and corrected authorization error messages to reference "delivery orders"; added an extensive delivery order API test suite; renamed a supply delivery test base class, added a subclass, and included a price_components entry in charge item definition test data.

Changes

Cohort / File(s) Summary
Authorization & Retrieval Logic
care/emr/api/viewsets/inventory/delivery_order.py
Changed authorization error messages to reference "delivery orders". Rewrote authorize_retrieve to require read access on at least one of origin or destination (calls authorize_location_read(..., raise_error=False)), added docstring, and only raises PermissionDenied("Cannot read delivery orders") if neither grants access.
Delivery Order API Tests
care/emr/tests/test_delivery_order_api.py
Added comprehensive DRF tests covering creation, update, retrieve, and listing of delivery orders (internal/external), multiple permission scenarios (superuser, permitted, forbidden), origin/destination validation and filters (origin, destination, status, supplier, include_children, origin_isnull, destination_isnull), medication-return workflows including invoice generation, inventory net content adjustments on status changes, charge item status/amount checks, and various status transition edge cases.
Supply Delivery Tests Adjustments
care/emr/tests/test_supply_delivery.py
Renamed TestSupplyDeliveryViewSetTestSupplyDeliveryViewSetBase, introduced a TestSupplyDeliveryViewSet subclass that calls super().setUp(), and added a price_components entry to ChargeItemDefinition test data created with baker.make.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely incomplete, missing the 'Proposed Changes' and 'Associated Issue' sections required by the template. Add 'Proposed Changes' section with brief of changes made and 'Associated Issue' section with link and explanation of how the solution addresses it.
Docstring Coverage ⚠️ Warning Docstring coverage is 77.05% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change—comprehensive test cases for delivery order functionality—which aligns with the substantial new test file and modifications to existing tests.

✏️ 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 test/delivery_order

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (3)
care/emr/api/viewsets/inventory/delivery_order.py (1)

122-137: authorize_retrieve logic matches intent; consider minor readability tweak

The new logic (require read access to origin or destination, using raise_error=False and a single PermissionDenied("Cannot read delivery orders")) matches the docstring and keeps failure messaging consistent. If you ever touch this again, you might consider naming the booleans (origin_allowed, destination_allowed) to avoid the nested parentheses, but as is it’s still quite readable.

care/emr/tests/test_delivery_order_api.py (2)

33-40: FacilityLocationOrganization helper may bind locations to the wrong facility_organization

create_facility_location always uses self.facility_organization, even when creating locations for another facility (e.g., in the mismatched origin/destination test). That can produce FacilityLocationOrganization rows where organization.facility doesn’t match location.facility, which is confusing at best.

It’s a small test‑only thing, but it would be cleaner to either:

  • accept a facility_organization argument, or
  • create a matching facility_organization for the passed facility inside this helper.

379-477: Retrieve tests validate basic permission boundaries; partial-access cases could be added later

You’re covering internal vs external orders and the with/without permission cases, including the “Cannot read delivery orders” message. That matches the new authorize_retrieve behavior.

If you ever need to exercise the “origin OR destination” semantics more explicitly, additional tests where a user has access to only one side (origin‑only or destination‑only) would make that logic harder to accidentally break, but it’s not strictly required to merge this.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd49643 and 25f9b3d.

📒 Files selected for processing (2)
  • care/emr/api/viewsets/inventory/delivery_order.py (3 hunks)
  • care/emr/tests/test_delivery_order_api.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (.cursorrules)

**/*.py: Prioritize readability and maintainability; follow Django's coding style guide (PEP 8 compliance).
Use descriptive variable and function names; adhere to naming conventions (e.g., lowercase with underscores for functions and variables).

Files:

  • care/emr/api/viewsets/inventory/delivery_order.py
  • care/emr/tests/test_delivery_order_api.py
**/tests/**/*.py

📄 CodeRabbit inference engine (.cursorrules)

Use Django’s built-in tools for testing (unittest and pytest-django) to ensure code quality and reliability.

Files:

  • care/emr/tests/test_delivery_order_api.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: rithviknishad
Repo: ohcnetwork/care PR: 3176
File: care/emr/api/viewsets/inventory/product_knowledge.py:33-40
Timestamp: 2025-07-30T12:06:18.804Z
Learning: In EMR viewsets using EMRUpsertMixin, the upsert method properly handles authorization by delegating to handle_update() and handle_create(), which in turn call authorize_update() and authorize_create() respectively. No separate authorize_upsert() method is needed.
🧬 Code graph analysis (2)
care/emr/api/viewsets/inventory/delivery_order.py (3)
care/emr/api/viewsets/inventory/request_order.py (1)
  • authorize_location_read (71-78)
care/emr/api/viewsets/inventory/supply_delivery.py (1)
  • authorize_location_read (140-147)
care/emr/api/viewsets/inventory/dispense_order.py (1)
  • authorize_location_read (54-57)
care/emr/tests/test_delivery_order_api.py (4)
care/emr/models/location.py (2)
  • FacilityLocation (12-127)
  • FacilityLocationOrganization (130-143)
care/emr/resources/inventory/supply_delivery/delivery_order.py (1)
  • SupplyDeliveryOrderStatusOptions (18-24)
care/security/permissions/supply_delivery.py (1)
  • SupplyDeliveryPermissions (16-37)
care/utils/tests/base.py (4)
  • CareAPITestBase (22-128)
  • create_facility_organization (46-49)
  • create_role_with_permissions (58-71)
  • attach_role_facility_organization_user (112-115)
🪛 Ruff (0.14.4)
care/emr/api/viewsets/inventory/delivery_order.py

72-72: Avoid specifying long messages outside the exception class

(TRY003)


81-81: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test / Test
🔇 Additional comments (4)
care/emr/api/viewsets/inventory/delivery_order.py (1)

67-83: Updated error messages look correct and consistent

The switched messages to "Cannot list/write delivery orders" match the domain language and the expectations in the new tests. The authorization wiring still mirrors the other inventory viewsets, so behavior is preserved apart from the wording change.

care/emr/tests/test_delivery_order_api.py (3)

71-200: Create‑flow tests are thorough and aligned with the viewset behavior

The create tests cover internal vs external orders, superuser vs permissioned vs unpermissioned users, and the cross‑facility origin/destination validation. Assertions on the exact error messages for forbidden writes and mismatched facilities line up with the viewset changes and should catch regressions nicely.


203-376: Update‑flow tests give good coverage for internal/external + permissions

The update tests mirror the create cases (internal/external, superuser, permissioned, unpermissioned) and validate both success paths and the “Cannot write delivery orders” failure. This lines up with authorize_update’s origin/destination ownership rules, so you’ve got solid guard rails here.


558-888: Filter and hierarchy tests give strong coverage of list behavior

The origin/destination filters, include_children, origin_isnull, and supplier/status combinations are all exercised with both positive and negative cases. That aligns nicely with DeliveryOrderFilters and filter_location_queryset, and should keep any future refactors of the filtering logic honest.

Comment thread care/emr/tests/test_delivery_order_api.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
care/emr/tests/test_delivery_order_api.py (1)

45-52: create_facility_location is duplicated from TestSupplyDeliveryViewSetBase.

This exact helper (make a FacilityLocation + FacilityLocationOrganization) already exists in TestSupplyDeliveryViewSetBase. Consider pulling it up into CareAPITestBase so both test classes can share it. Or not — I'm sure copy-paste is a perfectly valid design pattern.

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

In `@care/emr/tests/test_delivery_order_api.py` around lines 45 - 52, Duplicate
helper create_facility_location exists in TestSupplyDeliveryViewSetBase and this
test file; move the shared logic into CareAPITestBase (or a common test base) as
a single method definition that creates FacilityLocation and
FacilityLocationOrganization, then update TestSupplyDeliveryViewSetBase and this
test to call CareAPITestBase.create_facility_location (or remove the duplicate
here and inherit it). Ensure the method signature and baker.make calls (creating
FacilityLocation and FacilityLocationOrganization with facility and
facility_organization) remain the same so tests using create_facility_location
keep their behavior.
care/emr/tests/test_supply_delivery.py (1)

211-214: Redundant setUp override.

This setUp only calls super().setUp() and adds nothing else. You could omit it entirely — Python will call the parent's setUp automatically. But hey, I'm sure there was a very important reason to keep it.

♻️ Suggested simplification
 class TestSupplyDeliveryViewSet(TestSupplyDeliveryViewSetBase):
-    def setUp(self):
-        super().setUp()
-
-    def test_create_supply_delivery_internally_as_superuser(self):
+    def test_create_supply_delivery_internally_as_superuser(self):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@care/emr/tests/test_supply_delivery.py` around lines 211 - 214, The
TestSupplyDeliveryViewSet class contains a redundant setUp method that only
calls super().setUp(); remove the setUp override from class
TestSupplyDeliveryViewSet so the parent TestSupplyDeliveryViewSetBase.setUp will
be used automatically, keeping behavior unchanged and eliminating dead code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@care/emr/tests/test_delivery_order_api.py`:
- Around line 956-968: The triple-quoted string inside the setUp method is
placed after super().setUp() so it is treated as a dead string expression rather
than documentation; fix by moving that multi-line string immediately after the
def setUp(self): line (so it becomes the method docstring) or replace the
triple-quoted block with equivalent # comments, and ensure the call to
super().setUp() remains after the docstring; refer to the setUp method in the
TestSupplyDeliveryViewSetBase-derived test class to locate and update the block.

---

Duplicate comments:
In `@care/emr/tests/test_delivery_order_api.py`:
- Around line 545-621: The tests test_list_delivery_orders_as_superuser,
test_list_delivery_orders_as_user_with_permission, and
test_list_delivery_orders_as_user_without_permission currently use
len(response.data) which counts top-level dict keys; change those assertions to
check the number of returned orders instead (e.g.,
assertEqual(len(response.data["results"]), 2) or
assertEqual(response.data.get("count"), 2)) and update any similar len(...)
checks to reference "results" or "count"; also flag the inconsistent
authorization behavior (200 vs 403) for the unpermitted user so the reviewer can
confirm intended behavior.

---

Nitpick comments:
In `@care/emr/tests/test_delivery_order_api.py`:
- Around line 45-52: Duplicate helper create_facility_location exists in
TestSupplyDeliveryViewSetBase and this test file; move the shared logic into
CareAPITestBase (or a common test base) as a single method definition that
creates FacilityLocation and FacilityLocationOrganization, then update
TestSupplyDeliveryViewSetBase and this test to call
CareAPITestBase.create_facility_location (or remove the duplicate here and
inherit it). Ensure the method signature and baker.make calls (creating
FacilityLocation and FacilityLocationOrganization with facility and
facility_organization) remain the same so tests using create_facility_location
keep their behavior.

In `@care/emr/tests/test_supply_delivery.py`:
- Around line 211-214: The TestSupplyDeliveryViewSet class contains a redundant
setUp method that only calls super().setUp(); remove the setUp override from
class TestSupplyDeliveryViewSet so the parent
TestSupplyDeliveryViewSetBase.setUp will be used automatically, keeping behavior
unchanged and eliminating dead code.

Comment thread care/emr/tests/test_delivery_order_api.py
@praffq

praffq commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Tests failing

@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a comprehensive test suite for the delivery order API and makes two targeted fixes to DeliveryOrderViewSet: all four PermissionDenied messages are updated from "supply requests" to "delivery orders", and authorize_retrieve is refactored to correctly grant access when the user has read permission on either the origin or destination (using raise_error=False and short-circuit OR), fixing the previous behaviour that would immediately raise on origin failure even when destination was accessible.

  • delivery_order.py: Error messages and authorize_retrieve OR-logic are correct; the perform_update guard that blocks abandoned status for patient orders is exercised by the new cancellation tests, which now correctly use entered_in_error instead of abandoned.
  • test_delivery_order_api.py: ~1300-line test file covering internal/external create, update, retrieve, list, filters, permission, status-transition, and medication-return/cancellation flows. The three unfiltered list tests still call len(response.data) instead of len(response.data[\"results\"]) — those assertions will fail under DRF pagination (already flagged in prior review rounds).
  • test_supply_delivery.py: TestSupplyDeliveryViewSetBase extracted for reuse; price_components added to the ChargeItemDefinition fixture to support invoice price assertions in the new medication-return tests.

Confidence Score: 4/5

Safe to merge once the three list-test len(response.data) assertions are corrected; the viewset changes themselves are correct.

The viewset fixes are clean and the medication-return tests correctly use entered_in_error. However, three unfiltered list tests assert len(response.data) == 2 rather than len(response.data["results"]) == 2; these will produce AssertionError: 4 != 2 under DRF pagination, meaning those test cases will never pass as written. These were flagged in the previous review round but remain unaddressed.

care/emr/tests/test_delivery_order_api.py — the three unfiltered list tests at lines 632, 661, and 685

Important Files Changed

Filename Overview
care/emr/api/viewsets/inventory/delivery_order.py Error messages updated from 'supply requests' to 'delivery orders'; authorize_retrieve fixed to correctly allow OR-access on origin or destination using raise_error=False; authorize_order_write message also corrected. Logic is clean and correct.
care/emr/tests/test_delivery_order_api.py New 1322-line test file covering create/update/retrieve/list/filter/permission/medication-return flows. Three list tests still use len(response.data) instead of len(response.data['results']) (already flagged). self.return_medication is set up but never referenced in any test.
care/emr/tests/test_supply_delivery.py TestSupplyDeliveryViewSet extracted into TestSupplyDeliveryViewSetBase for reuse; price_components added to ChargeItemDefinition fixture to support invoice price assertions. No-op setUp override in TestSupplyDeliveryViewSet remains (already flagged).

Reviews (3): Last reviewed commit: "Merge remote-tracking branch 'origin/tes..." | Re-trigger Greptile

Comment on lines +558 to +569
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)

def test_list_delivery_orders_as_user_with_permission(self):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 len(response.data) counts dict keys, not result items, so these assertions always produce the wrong number

When DRF pagination is active, response.data is an OrderedDict with keys count, next, previous, results. len(response.data) returns 4 (the number of dict keys), never 2. The same test file already uses len(response.data["results"]) consistently in every other list test (e.g., lines 692, 789, 876), so these three assertions are out of step with the rest of the suite and will fail whenever pagination is applied.

Suggested change
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)
def test_list_delivery_orders_as_user_with_permission(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data["results"]), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)
def test_list_delivery_orders_as_user_with_permission(self):

Comment on lines +587 to +598
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)

def test_list_delivery_orders_as_user_without_permission(self):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Same len(response.data) issue in the user-with-permission list test. Should reference response.data["results"] for consistency with the rest of the file.

Suggested change
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)
def test_list_delivery_orders_as_user_without_permission(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data["results"]), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)
def test_list_delivery_orders_as_user_without_permission(self):

Comment on lines +611 to +622
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)

def test_list_delivery_orders_with_origin_filter(self):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Same len(response.data) issue in the user-without-permission list test.

Suggested change
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)
def test_list_delivery_orders_with_origin_filter(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data["results"]), 2)
self.assertIn(
str(delivery_order1.external_id),
[order["id"] for order in response.data["results"]],
)
self.assertIn(
str(delivery_order2.external_id),
[order["id"] for order in response.data["results"]],
)
def test_list_delivery_orders_with_origin_filter(self):

Comment on lines +212 to 216
class TestSupplyDeliveryViewSet(TestSupplyDeliveryViewSetBase):
def setUp(self):
super().setUp()

def test_create_supply_delivery_internally_as_superuser(self):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 The setUp override in TestSupplyDeliveryViewSet is a no-op — it just calls super().setUp(), which Python would invoke automatically via inheritance. The override can be removed.

Suggested change
class TestSupplyDeliveryViewSet(TestSupplyDeliveryViewSetBase):
def setUp(self):
super().setUp()
def test_create_supply_delivery_internally_as_superuser(self):
class TestSupplyDeliveryViewSet(TestSupplyDeliveryViewSetBase):
def test_create_supply_delivery_internally_as_superuser(self):

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread care/emr/tests/test_delivery_order_api.py
@vigneshhari vigneshhari changed the title Test cases for delivery order [ENG-88] Test cases for delivery order Jun 23, 2026
@vigneshhari vigneshhari merged commit c8baced into develop Jun 23, 2026
14 checks passed
@vigneshhari vigneshhari deleted the test/delivery_order branch June 23, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants