docs: add notification and concurrency test procedures
This commit is contained in:
160
11 - Testing/Notification Assertion Procedure.md
Normal file
160
11 - Testing/Notification Assertion Procedure.md
Normal file
@@ -0,0 +1,160 @@
|
||||
---
|
||||
title: Notification Assertion Procedure
|
||||
tags: [testing, notifications, e2e, socket-io]
|
||||
created: 2026-06-06
|
||||
---
|
||||
|
||||
# Notification Assertion Procedure
|
||||
|
||||
Every E2E business step must verify notifications. A test step is incomplete
|
||||
until notification persistence and, where practical, real-time delivery are
|
||||
validated.
|
||||
|
||||
Related docs:
|
||||
|
||||
- [[04 - Flows/Notification Flow]]
|
||||
- [[03 - API Reference/Notification API]]
|
||||
- [[Escrow Marketplace E2E Procedure]]
|
||||
|
||||
## Principle
|
||||
|
||||
For each state-changing action, assert notifications for the expected recipients.
|
||||
If the product currently does not emit a notification for that action, the E2E
|
||||
must record a notification coverage gap. Silent missing notifications should not
|
||||
be treated as a pass.
|
||||
|
||||
## Notification Channels To Check
|
||||
|
||||
| Channel | Required? | How |
|
||||
|---|---|---|
|
||||
| Persistence | Always | `GET /api/notifications`, `GET /api/notifications/unread-count` |
|
||||
| Socket push | Required when runner has sockets enabled | Listen for `new-notification` on `user-<userId>` |
|
||||
| Badge count sync | Required for read/mark-read steps | `unread-count-update` socket event or count endpoint |
|
||||
| Email/push | Not required today | Planned digest/push work is not implemented |
|
||||
|
||||
## Baseline Before a Scenario
|
||||
|
||||
For every actor:
|
||||
|
||||
1. Authenticate.
|
||||
2. Read unread count:
|
||||
```http
|
||||
GET /api/notifications/unread-count
|
||||
```
|
||||
3. Read latest notifications:
|
||||
```http
|
||||
GET /api/notifications?page=1&limit=5
|
||||
```
|
||||
4. Store:
|
||||
- `baselineUnreadCount`;
|
||||
- latest notification id;
|
||||
- timestamp.
|
||||
|
||||
Do this before creating purchase requests or offers so later assertions can
|
||||
distinguish new notifications from old ones.
|
||||
|
||||
## Per-Step Assertion Algorithm
|
||||
|
||||
After each action:
|
||||
|
||||
1. Identify expected recipients.
|
||||
2. Poll each recipient's notifications for up to the notification SLA window.
|
||||
3. Assert at least one new notification matching the action.
|
||||
4. Assert unread count increased by the expected number, unless the notification
|
||||
is intentionally auto-read.
|
||||
5. Assert `actionUrl` or `relatedId` points to the correct request/payment/offer
|
||||
where the notification type supports it.
|
||||
6. If socket instrumentation is active, assert the same notification arrived via
|
||||
`new-notification`.
|
||||
7. Record `notificationLatencyMs = notification.createdAt - actionCompletedAt`
|
||||
or runner-observed first-seen time.
|
||||
|
||||
Suggested polling:
|
||||
|
||||
| Target | Value |
|
||||
|---|---:|
|
||||
| poll interval | `500 ms` |
|
||||
| timeout | `10 s` for local/dev API notifications |
|
||||
| hard failure threshold | `30 s` |
|
||||
|
||||
## Expected Marketplace Notifications
|
||||
|
||||
| Action | Expected recipients | Expected category/type |
|
||||
|---|---|---|
|
||||
| Buyer creates request | eligible sellers | `purchase_request` / new request or opportunity |
|
||||
| Seller submits offer | buyer | `offer` / new offer |
|
||||
| Buyer accepts offer | selected seller | `offer` / accepted |
|
||||
| Buyer accepts offer | non-selected sellers | `offer` / rejected or no-longer-selected, when implemented |
|
||||
| Payment intent created | buyer | `payment` / pending or started, when implemented |
|
||||
| Scanner confirms payment | buyer, selected seller | `payment` / confirmed or funded |
|
||||
| Seller marks delivery | buyer | `delivery` / delivery submitted |
|
||||
| Buyer confirms delivery | selected seller | `delivery` / delivery confirmed |
|
||||
| Dispute raised | buyer, seller, admin/mediator | `delivery`/`payment`/`system` dispute hold, when implemented |
|
||||
| Release/refund | buyer, seller | `payment` / release or refund |
|
||||
|
||||
Known current gaps from existing docs:
|
||||
|
||||
- `pending_payment` and `seller_paid` status changes are not covered by
|
||||
`NotificationService.notifyRequestStatusChanged`.
|
||||
- Dispute service notification emits are TODO stubs in the dashboard dispute path.
|
||||
|
||||
These known gaps should still be reported by the E2E runner as gaps, not ignored.
|
||||
|
||||
## Evidence Format
|
||||
|
||||
For each step, append a notification assertion record:
|
||||
|
||||
```json
|
||||
{
|
||||
"step": "seller_offer_created",
|
||||
"recipient": "buyer",
|
||||
"recipientUserId": "<id>",
|
||||
"expected": true,
|
||||
"observed": true,
|
||||
"latencyMs": 742,
|
||||
"unreadBefore": 3,
|
||||
"unreadAfter": 4,
|
||||
"notificationId": "<id>",
|
||||
"category": "offer",
|
||||
"actionUrl": "/dashboard/request/<requestId>",
|
||||
"socketObserved": true,
|
||||
"gap": null
|
||||
}
|
||||
```
|
||||
|
||||
For a known gap:
|
||||
|
||||
```json
|
||||
{
|
||||
"step": "payment_intent_created",
|
||||
"recipient": "buyer",
|
||||
"expected": true,
|
||||
"observed": false,
|
||||
"gap": "No notification emitted for pending_payment status",
|
||||
"linkedDoc": "Notification Flow#Purchase request status coverage gap"
|
||||
}
|
||||
```
|
||||
|
||||
## Pass/Fail Rules
|
||||
|
||||
| Condition | Result |
|
||||
|---|---|
|
||||
| Expected notification appears within SLA | pass |
|
||||
| Expected notification appears after SLA but before hard timeout | warning |
|
||||
| Expected notification never appears and no approved gap exists | fail |
|
||||
| Notification appears for wrong user | fail |
|
||||
| Notification exists but has wrong request/payment/offer id | fail |
|
||||
| Socket missing but persistence exists | warning unless socket coverage is the target |
|
||||
| Unread count inconsistent with persisted notification | fail |
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
Notification metrics must be included in concurrency profiles:
|
||||
|
||||
- notification persistence latency p50/p95/p99;
|
||||
- socket delivery latency p50/p95/p99;
|
||||
- notification failures by action and recipient;
|
||||
- unread count mismatch rate;
|
||||
- duplicate notification rate;
|
||||
- Mongo notification insert error rate.
|
||||
|
||||
Reference in New Issue
Block a user