Commera

Commera

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

Testing

Test your plugin at three levels: call the handler directly, run the real delivery queue in a test, and check the rows on a development site.

Call the handler directly

Build a CommeraEvent and call your handler. Run it as the plugin user, the same user that runs real deliveries.

import frappe
from frappe.tests import IntegrationTestCase
from frappe.utils import now_datetime
from commera.sdk.events import CommeraEvent

from my_app.orders import on_order_paid


def make_order_event(sales_order: str, name: str, data: dict | None = None) -> CommeraEvent:
	return CommeraEvent(
		id=f"{sales_order}-{name}",
		name=name,
		reference_doctype="Sales Order",
		reference_name=sales_order,
		data=data or {},
		created_at=now_datetime(),
	)


class TestOrders(IntegrationTestCase):
	def test_a_repeated_paid_event_makes_one_job(self):
		event = make_order_event(self.sales_order, "order_paid")
		frappe.set_user("commera-plugins@commera.local")
		self.addCleanup(frappe.set_user, "Administrator")

		on_order_paid(event)
		on_order_paid(event)

		self.assertEqual(frappe.db.count("My Job", {"event_id": event.id}), 1)

Call the handler twice in one test. Delivery is at least once, so a second call must do nothing.

Code that commits

A handler or method that calls frappe.db.commit() writes past the test rollback. Patch the commit in the test:

from unittest.mock import patch

import frappe


class TestSendOrder(IntegrationTestCase):
	def setUp(self):
		commit_patch = patch.object(frappe.db, "commit")
		commit_patch.start()
		self.addCleanup(commit_patch.stop)

Fake the cart for a hook

A hook reads quotation.items and fields such as quotation.grand_total. Use types.SimpleNamespace for a fake cart. frappe._dict(items=[...]) does not work, because .items is the dict method.

from types import SimpleNamespace

from my_app.cart import get_cart_refusal

cart = SimpleNamespace(name="test-cart", items=[SimpleNamespace(item_code="TSHIRT-RED-M")])
self.assertIsNone(get_cart_refusal(cart))

If your hook calls quotation.get(...), build the fake with frappe._dict for the fields and a separate attribute for the lines, or test against a real Quotation.

Run the real delivery queue

To test the whole path, run Commera's background jobs inline. Do not patch frappe.enqueue away: Commera queues each delivery with it.

from unittest.mock import patch

import frappe


def run_enqueued_jobs_now(test_case):
	enqueue = frappe.enqueue

	def enqueue_now(method, *args, **kwargs):
		kwargs.update(now=True, enqueue_after_commit=False)
		return enqueue(method, *args, **kwargs)

	for enqueue_patch in (
		patch.object(frappe, "enqueue", side_effect=enqueue_now),
		patch.object(frappe.db, "commit"),
		patch.object(frappe.db, "rollback"),
	):
		enqueue_patch.start()
		test_case.addCleanup(enqueue_patch.stop)

Call it in setUp, make a store order, and check that your handler's record exists. A real order needs Order Type Shopping Cart, or no order event fires.

On a development site

  1. Place an order on the storefront.
  2. In /commera, open Settings > Plugins and click Open next to your plugin. Recent deliveries shows each delivery and its status. See deliveries lists the statuses.
  3. If a delivery failed, open Error Log in Desk. The title is commera_events["<event>"] hook failed: <handler>.
  4. Fix the code. Then, as a System Manager, click Retry on the Failed delivery.

To read the rows from bench --site <site> console:

frappe.get_all("Commera Event", filters={"reference_name": "SAL-ORD-2026-00062"}, fields=["name", "event"])
frappe.get_all(
	"Commera Event Delivery",
	filters={"parent": "SAL-ORD-2026-00062-order_paid"},
	fields=["app", "handler", "status"],
)

Make sure that the scheduler and a worker run on the site. Retries wait for the scheduler, and every delivery runs in a worker.

Next steps

Last updated 3 days ago
Was this helpful?
Thanks!