> For the complete documentation index, see [llms.txt](https://orbit-b2b.gitbook.io/orbit-b2b-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://orbit-b2b.gitbook.io/orbit-b2b-docs/b2b-customer-portal/testing.md).

# Testing the customer flow

End-to-end test plan for verifying the reorder portal works on your dev store.

## Prereqs

1. Reorder reminders enabled (Apps → Orders → Reorder Settings → Schedule → Enable ON)
2. At least one Customer Group with a test customer in it
3. Customer has an email address on Shopify (`customer.email`)
4. SMTP configured (Settings → Email Settings → SMTP)
5. Test customer's `emailMarketingConsent.marketingState` is `SUBSCRIBED` (if your settings require it)

## Test 1: Portal access (eligible customer)

1. Log into the storefront as your test B2B customer
2. Navigate directly to: `https://your-shop.myshopify.com/apps/orbit-boost-wholesale/portal/orders`
3. Expected: orders list page with recent orders + Reorder buttons
4. Click **Reorder** on any order
5. Expected: `/portal/reorder?order=<id>` page loads with each line item, checkbox, qty stepper, B2B price
6. Adjust qty / deselect items
7. Click **Add selected to cart**
8. Expected: cart updates with selected items + redirect to `/cart`

## Test 2: Portal access (ineligible customer)

1. Log in as a non-B2B customer (no Customer Group membership)
2. Navigate to `/apps/orbit-boost-wholesale/portal/orders`
3. Expected: "Reorder is available for B2B accounts only" message

## Test 3: Portal access (guest)

1. Log out completely
2. Navigate to `/apps/orbit-boost-wholesale/portal/orders`
3. Expected: "Please log in to reorder" message

## Test 4: Reminder email cron

The cron runs daily at 06:00 UTC. To force a same-day test:

1. In Reorder Settings → Schedule, set **First reminder** to `0` days (or whatever delay you want to test)
2. Save
3. Place a test order on the storefront as your B2B customer
4. Fulfill the order in Shopify Admin → Orders
5. Wait for 06:00 UTC (or trigger the cron manually if you have backend access — see below)
6. Customer email inbox should receive a reminder

### Triggering the cron manually (dev only)

If you have backend SSH access or run the app locally:

```bash
cd backend
node -e "import('./jobs/reorderReminderJob.js').then(m => m.runDaily()).then(() => process.exit(0))"
```

Watch logs for `[reorderReminderJob]` lines indicating which shops were processed and which orders matched.

## Test 5: Unsubscribe link

1. Receive a reminder email (Test 4)
2. Click the unsubscribe link at the bottom
3. Expected: "You have been unsubscribed from reorder reminder emails from this store" confirmation page
4. Verify in MongoDB: `ReorderUnsubscribe` collection has a new entry with hashed email
5. Future cron runs should skip this customer

## Test 6: Reminder dedupe

1. Run the cron once for a delay → customer gets email A
2. Re-run the cron same day → customer should NOT get a second email
3. Verify: `ReorderReminder` collection has exactly one entry with `(shop, orderId, step=1)`

## Test 7: Marketing consent gate

1. In Reorder Settings → Schedule, ensure **Only send to customers with marketing consent** is ON
2. In Shopify Admin → Customers → your test customer → set email marketing to `Unsubscribed` (or never opted in)
3. Trigger cron
4. Customer should NOT receive reminder
5. Set their consent back to `Subscribed`
6. Trigger cron next day (or skip dedupe via DB reset)
7. Customer should receive reminder

## Test 8: Wholesale-aware pricing

1. Place an order as a customer with no B2B group (retail price)
2. Add that customer to a B2B Customer Group with a Wholesale Discount rule (e.g. 20% off all products)
3. Visit `/portal/reorder?order=<original_order_id>` as that customer
4. Expected: each line item's price shows the WHOLESALE price (post-discount), not the retail price the original order was placed at
5. Add selected to cart → cart confirms the wholesale price

## Test 9: Out-of-stock variant

1. Set one variant's inventory to 0 (track inventory + zero stock)
2. Reorder an old order that includes that variant
3. Expected: the variant's row shows "Out of stock" status, checkbox disabled, qty stepper readonly
4. Add selected → only available items added to cart

## Test 10: Discontinued variant

1. Delete a variant from a product that's in a customer's order history
2. Reorder that order
3. Expected: the variant's row shows "No longer available", checkbox disabled, row dimmed

## Troubleshooting

* **No orders shown** → customer has no orders or wasn't tagged `orb2b-b2b`. Check Shopify Admin → Orders for the `orb2b-b2b` tag
* **"Not eligible" but customer should be eligible** → verify customer's Shopify customer record has the group tag. CustomerGroupService syncs tags via webhook; check logs for `tagsAdd` confirmations
* **Reminder cron didn't run** → check backend logs for `[scheduledJobs]` + `[reorderReminderJob]`. Verify Mongo lock isn't stuck (look at `Lock` collection for `reorder_reminder_daily`)
* **Email didn't arrive** → check SMTP config + Settings → Email Settings → Send a test email. Check spam folder

## Next

* [Schedule (when reminders fire)](/orbit-b2b-docs/b2b-customer-portal/schedule.md)
* [Customize the email template](/orbit-b2b-docs/b2b-customer-portal/email-template.md)
* [Design the portal pages](/orbit-b2b-docs/b2b-customer-portal/design.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://orbit-b2b.gitbook.io/orbit-b2b-docs/b2b-customer-portal/testing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
