Skip to content

Test Cases: Product

ModuleCORE-05URDProduct URD

Scenarios use Given / When / Then. TC-<AREA>-NNN lines up with URD-<AREA>-NNN. Priority = P1 (critical) / P2 (major) / P3 (minor).

1. Coverage Summary

AreaURD reqsTest casesCovered
Product (PRD)1631
Category (CAT)48
Variant (VAR)1224
Fare / Pricing (FAR)717
Identifiers (PID)48
Promotions (CMP)35⚠️ (calc Planned)
Access (ACC)411
Constraints (CON)713

The variant pricing-read endpoint (URD-VAR-011), CSV import (URD-PRD-019), and promotion discount calculation (URD-CMP-003) are Planned / In-progress; their test cases verify the current behavior (error / not-applied), not full functionality.

2. Test Cases

2.1 Product (PRD)

TC IDURD refScenarioStepsExpectedP
TC-PRD-001URD-PRD-001, -002, -004Create product (happy path)Owner creates product with name + categoryCreated; SYSTEM id + slug generated; default variant created; status ActivatedP1
TC-PRD-002URD-PRD-001Create without nameSubmit with no nameRejected; name requiredP1
TC-PRD-003URD-PRD-001Create without categorySubmit with no categoryRejected; category requiredP1
TC-PRD-004URD-PRD-003Multilingual nameProvide name in EN + VIAll languages stored & retrievableP1
TC-PRD-005URD-PRD-003Partial languagePrimary name only, others emptyCreated; empty languages stored as empty (no error)P2
TC-PRD-006URD-PRD-005Update infoOwner updates name & descriptionUpdated; variants/fares unchangedP1
TC-PRD-007URD-PRD-005Update to empty nameOwner clears the nameRejected; original preservedP1
TC-PRD-008URD-PRD-006DeactivateOwner deactivates an active productStatus Deactivated; data preserved; hidden from POSP1
TC-PRD-009URD-PRD-006View deactivatedOwner opens a deactivated productAll data intact; status shows DeactivatedP2
TC-PRD-010URD-PRD-007Slug collision same merchantCreate a product that would reuse an existing slugSystem ensures uniqueness (distinct slugs)P1
TC-PRD-011URD-PRD-007Slug across merchantsTwo merchants both create "coffee-latte"Both succeed; slug unique per merchant, may match across merchantsP2
TC-PRD-012URD-PRD-008Lookup by IDSearch by known IDProduct returned with name, category, status, variantsP1
TC-PRD-013URD-PRD-008Lookup by slugSearch by known slugProduct returnedP1
TC-PRD-014URD-PRD-008Lookup missing IDSearch by non-existent IDNot found; nothing returnedP2
TC-PRD-015URD-PRD-009List (role-filtered)Owner requests product listOnly products under own merchants returnedP1
TC-PRD-016URD-PRD-009Count consistencyOwner requests product countCount respects the same role filter as the listP2
TC-PRD-017URD-PRD-013Attach imageOwner attaches imagesImages linked & retrievableP2
TC-PRD-018URD-PRD-013Bad image formatOwner uploads unsupported formatRejected; allowed formats indicatedP3
TC-PRD-019URD-PRD-014Assign sale channelsOwner assigns product to specific channelsAvailable only in assigned channelsP2
TC-PRD-020URD-PRD-014Remove from channelRemove product from channel BStays in A; gone from BP2
TC-PRD-021URD-PRD-016Parent-childCreate a child product under a parentChild references parent; parent lists childrenP2
TC-PRD-023URD-PRD-006ArchiveOwner archives a productStatus Archived; data preserved; hidden from POS & listP1
TC-PRD-024URD-PRD-008Lookup missing slugSearch by non-existent slugNot found; nothing returnedP2
TC-PRD-025URD-PRD-006ReactivateOwner reactivates a deactivated productStatus Activated; visible again; data unchangedP1
TC-PRD-026URD-PRD-001Create without merchantOwner creates without merchant contextRejected; merchant requiredP1
TC-PRD-027URD-PRD-007Empty-string slugOwner submits "" as slugSystem auto-generates a valid slug; product findableP2
TC-PRD-028URD-PRD-014Channel diff updateUpdate channels [A,B,C] → [B,D]A & C removed, D added, B kept — atomicallyP2
TC-PRD-029URD-PRD-005, -014Channel-only updateAggregate update with no product change, new channelsProduct unchanged; channels updated; no redundant product writeP2
TC-PRD-030URD-PRD-017Search by nameSearch "Cafe" across productsCase-insensitive partial matches returnedP1
TC-PRD-031URD-PRD-017Diacritics searchSearch "ca phe" against diacritic nameReturned if i18n search normalizes diacritics; behavior documentedP2
TC-PRD-032URD-PRD-018Filter by categoryFilter list by "Beverages"Only Beverages products returnedP1
TC-PRD-033URD-PRD-015Archived is read-onlyUpdate an archived productRejected; archived is read-onlyP1
TC-PRD-034URD-PRD-015Archive is terminalReactivate an archived productRejected; Archived is terminalP1
TC-PRD-022URD-PRD-019CSV import (Planned)Upload a catalogue fileFeature Planned — test expanded when implementedP3

2.2 Category (CAT)

TC IDURD refScenarioStepsExpectedP
TC-CAT-001URD-CAT-001Create categoryOwner creates a category with a nameCreated within merchant; available for assignmentP1
TC-CAT-002URD-CAT-001Create without nameSubmit with no nameRejected; name requiredP1
TC-CAT-003URD-CAT-002Multilingual nameProvide name in multiple languagesAll languages stored & retrievableP2
TC-CAT-004URD-CAT-003Update categoryOwner updates the nameUpdated; products unaffectedP2
TC-CAT-005URD-CAT-003Delete empty categoryDelete a category with no productsSoft-deleted; gone from listP2
TC-CAT-006URD-CAT-003Delete in-use categoryDelete a category with productsRejected; category in use; products keep assignmentP1
TC-CAT-007URD-CAT-004Flag add-onMark category as add-onFlagged; products treated as add-onP2
TC-CAT-008URD-CAT-004Unflag add-onRemove add-on flagReverts to standard category behaviorP3

2.3 Variant (VAR)

TC IDURD refScenarioStepsExpectedP
TC-VAR-001URD-VAR-001Default variant existsCreate a productDefault variant exists with a system identifierP1
TC-VAR-002URD-VAR-001Cannot delete last variantDelete the only variantRejected; at least one variant always remainsP1
TC-VAR-003URD-VAR-002Add variantCreate an additional "Large" variantLinked; product now has two variantsP1
TC-VAR-004URD-VAR-003, -005Aggregate createCreate variant + info + fares + identifiersAll created atomically; identifiers generatedP1
TC-VAR-005URD-VAR-003Aggregate create rollbackAggregate create with a negative fareWhole operation rejected; nothing createdP1
TC-VAR-006URD-VAR-004Aggregate updateUpdate name, fare, identifiers in one stepAll updated atomicallyP1
TC-VAR-007URD-VAR-004Aggregate update rollbackValid name but invalid fareWhole update rejected; originals preservedP1
TC-VAR-008URD-VAR-005System identifierCreate a variantUnique system identifier; not user-editableP2
TC-VAR-009URD-VAR-007Effective rangeSet from/to datesAvailable only inside the windowP2
TC-VAR-010URD-VAR-007Expired rangeEnd date in the past, add to cartNot available for saleP2
TC-VAR-011URD-VAR-006Set variant typeSet type to SERVICE / KIT / COMBO etc.Type stored; drives stocking & bundling behaviorP2
TC-VAR-012URD-VAR-008Assign SKUAssign an SKULinked; searchable by SKUP2
TC-VAR-013URD-VAR-008Assign barcodeAssign a barcodeLinked; searchable by barcodeP2
TC-VAR-014URD-VAR-001Deactivate variantDeactivate a non-only variantStatus Deactivated; data preserved; hidden from POSP1
TC-VAR-015URD-VAR-001Archive variantArchive a variantStatus Archived; data preserved; hidden from POS & listP1
TC-VAR-016URD-VAR-001New statusCreate a variantStatus New; not sellable until activatedP2
TC-VAR-017URD-VAR-001Activate variantActivate a New variantStatus Activated; sellableP2
TC-VAR-018URD-VAR-001Reactivate variantReactivate a deactivated variantStatus Activated; data unchangedP2
TC-VAR-019URD-VAR-011Pricing read (Planned)Call variant pricing endpointReturns a structured "not implemented" error, not a raw 500P2
TC-VAR-020URD-VAR-004Missing-merchant guardAggregate update on a variant lacking merchantId metadataRejected (500 by design); transaction rolled backP2
TC-VAR-021URD-VAR-004Fare-only updateUpdate only the fare amountName unchanged (no redundant write); fare updated; commitsP2
TC-VAR-022URD-VAR-008, URD-PID-004First-time SKU on updateVariant without SKU; update assigns SKUSKU created & linked, OR a clear error — never silently ignoredP2
TC-VAR-023URD-VAR-001Archived terminalTransition Archived → ActivatedRejected; Archived is terminalP1
TC-VAR-024URD-VAR-001Invalid skipTransition New → Archived directlyRejected; not a valid transitionP2

2.4 Fare / Pricing (FAR)

TC IDURD refScenarioStepsExpectedP
TC-FAR-001URD-FAR-001One fare setCreate a variantExactly one fare set linked; cannot be removedP1
TC-FAR-002URD-FAR-001No second fare setCreate a second fare setRejected; one fare set per variantP1
TC-FAR-003URD-FAR-002Base fare presentView a variant's fare setAt least one (default) fare existsP1
TC-FAR-004URD-FAR-002Cannot delete last fareDelete the only fareRejected; one fare must always existP1
TC-FAR-005URD-FAR-003Zero amount allowedCreate a fare of amount 0Created (zero allowed)P2
TC-FAR-006URD-FAR-003Negative rejectedCreate a fare of amount -100Rejected; amount must be ≥ 0P1
TC-FAR-007URD-FAR-004Base fare appliedAdd variant with only a base fareBase fare applied & displayedP1
TC-FAR-008URD-FAR-004Override winsVariant with base + active overrideOverride price selectedP1
TC-FAR-009URD-FAR-004All expiredAll fares have expired datesFalls back to the default fare; no expired price usedP1
TC-FAR-010URD-FAR-005In-window dateFare effective Mar 1–31, sale Mar 15Fare active & appliedP2
TC-FAR-011URD-FAR-005Out-of-window dateSame fare, sale Apr 1Not applied; next applicable fare usedP2
TC-FAR-012URD-FAR-006In quantity rangeFare min 10 / max 50, add 20Fare appliedP2
TC-FAR-013URD-FAR-006Below minimumFare min 10, add 5Not applied; next fare usedP2
TC-FAR-014URD-FAR-006Above maximumFare max 50, add 100Not applied; next fare usedP2
TC-FAR-015URD-FAR-007Fare group hierarchyParent fare with childrenParent-child maintained; children count correctP2
TC-FAR-016URD-FAR-004Create overrideAdd an OVERRIDE fare to a setOverride created; prioritized over base during resolutionP1
TC-FAR-017URD-FAR-004, -005, -006Multi-factor resolutionBase + quantity + seasonal override, add 15 on Mar 15Seasonal override selected (override priority); total = 15 × override amountP1

2.5 Identifiers (PID)

TC IDURD refScenarioStepsExpectedP
TC-PID-001URD-PID-001Per-scheme uniquenessReuse an SKU code on another productRejected; identifier already used for that schemeP1
TC-PID-002URD-PID-001Same code, different schemeSame code under SKU and BarcodeBoth accepted; uniqueness is per schemeP2
TC-PID-003URD-PID-002Multiple identifiersAssign across SYSTEM, SLUG, SKU, BarcodeAll stored; searchable by anyP1
TC-PID-004URD-PID-003Auto-generatedCreate a product / variantSYSTEM and SLUG auto-generated, unique, not editableP1
TC-PID-005URD-PID-003No identifier suppliedCreate without supplying an identifierSYSTEM & SLUG still generated; no errorP2
TC-PID-006URD-PID-004Assign SKU + barcodeAssign both to a variantBoth linked; searchable by eitherP2
TC-PID-007URD-PID-001, -004Duplicate SKUAssign an in-use SKU to another variantRejected; SKU already in useP1
TC-PID-008URD-PID-004Assign QR codeAssign a QR code to a variantLinked; searchable by QR codeP2

2.6 Promotions (CMP)

TC IDURD refScenarioStepsExpectedP
TC-CMP-001URD-CMP-001Create promotionCreate with name + date rangeCreated; linked to merchantP2
TC-CMP-002URD-CMP-001No date rangeCreate without datesRejected; date range requiredP2
TC-CMP-003URD-CMP-001Invalid rangeEnd date before startRejected; invalid rangeP2
TC-CMP-004URD-CMP-002Merchant scopeView Merchant A's promotion under Merchant BNot visible under BP2
TC-CMP-005URD-CMP-003Discount applied (Planned)Apply a promotion at pricingDiscount calc disabled today — returns 0; test expanded when engine landsP3

2.7 Access (ACC)

TC IDURD refScenarioStepsExpectedP
TC-ACC-001URD-ACC-001List filteredAny user lists productsFiltered by role; nothing outside scopeP1
TC-ACC-002URD-ACC-001Count filteredAny user counts productsCount reflects only in-scope productsP1
TC-ACC-003URD-ACC-002Owner scopeOwner A lists productsOnly A's merchants returned; B's hiddenP1
TC-ACC-004URD-ACC-002Cross-owner blockOwner A accesses Owner B's productDeniedP1
TC-ACC-005URD-ACC-003Employee scopeEmployee of X lists productsOnly X's products returnedP1
TC-ACC-006URD-ACC-003Employee blockEmployee of X accesses Y's productDeniedP1
TC-ACC-007URD-ACC-004Super Admin allSuper Admin lists productsAll products returned; no filteringP1
TC-ACC-008URD-ACC-004Admin allAdmin lists productsAll products; filtering bypassedP1
TC-ACC-009URD-ACC-001Category list filteredOwner lists categoriesOnly own merchants' categories returnedP1
TC-ACC-010URD-PRD-018Category filter scopeFilter products by categoryOnly that category's products returnedP2
TC-ACC-011URD-ACC-001Unrecognized roleUnhandled role lists products403 OR empty with clear insufficient-permission signal — never a silent empty listP1

2.8 Constraints (CON)

TC IDURD refScenarioStepsExpectedP
TC-CON-001C-01Single merchantAssign a product to a second merchantRejectedP1
TC-CON-002C-01Category-merchant matchAssign a foreign-merchant product to a categoryRejected; must share merchantP1
TC-CON-003C-06Soft-deleteSearch including inactive after deleteRecord still retrievable; data preservedP1
TC-CON-004URD-PID-003Auto-gen identifiersCreate without SYSTEM/SLUGBoth auto-generated, unique, consistentP1
TC-CON-005C-05Aggregate atomic createAggregate create with invalid fareWhole operation fails; nothing createdP1
TC-CON-006C-05Aggregate atomic updateValid name + invalid fare on updateWhole update fails; originals preservedP1
TC-CON-007C-07Role filter on listOwner lists productsFiltered before return; count matchesP1
TC-CON-008C-07Count matches listOwner with 5 products countsReturns 5, not the global totalP1
TC-CON-009URD-PRD-003i18n storageCreate with EN/VI/JA namesAll stored; returned per requested localeP1
TC-CON-010C-04One fare setView a new variant's pricingExactly one fare set, auto-createdP1
TC-CON-011C-04One fare minimumView a fare setAt least one fare; last fare cannot be removedP1
TC-CON-012C-05Sub-operation rollbackOne sub-step of aggregate product create failsWhole transaction rolled back; no orphansP1
TC-CON-013C-05Caller transaction ownershipA caller passes its own transaction to a lookupLookup neither commits nor rolls back; caller keeps controlP2

3. Traceability

Every Must requirement maps to ≥1 test case. Planned / In-progress items are flagged.

URD requirementTest case(s)Status
URD-PRD-001TC-PRD-001, -002, -003, -026✅ Covered
URD-PRD-002TC-PRD-001✅ Covered
URD-PRD-003TC-PRD-004, -005, TC-CON-009✅ Covered
URD-PRD-004TC-PRD-001✅ Covered
URD-PRD-005TC-PRD-006, -007, -029✅ Covered
URD-PRD-006TC-PRD-008, -009, -023, -025✅ Covered
URD-PRD-007TC-PRD-010, -011, -027✅ Covered
URD-PRD-008TC-PRD-012, -013, -014, -024✅ Covered
URD-PRD-009TC-PRD-015, -016, TC-ACC-009✅ Covered
URD-PRD-013TC-PRD-017, -018✅ Covered
URD-PRD-014TC-PRD-019, -020, -028, -029✅ Covered
URD-PRD-015TC-PRD-033, -034✅ Covered
URD-PRD-016TC-PRD-021✅ Covered
URD-PRD-017TC-PRD-030, -031✅ Covered
URD-PRD-018TC-PRD-032, TC-ACC-010✅ Covered
URD-PRD-019TC-PRD-022⚠️ Planned (Could)
URD-CAT-001TC-CAT-001, -002✅ Covered
URD-CAT-002TC-CAT-003✅ Covered
URD-CAT-003TC-CAT-004, -005, -006✅ Covered
URD-CAT-004TC-CAT-007, -008✅ Covered
URD-VAR-001TC-VAR-001, -002, -014, -015, -016, -017, -018, -023, -024✅ Covered
URD-VAR-002TC-VAR-003✅ Covered
URD-VAR-003TC-VAR-004, -005✅ Covered
URD-VAR-004TC-VAR-006, -007, -020, -021✅ Covered
URD-VAR-005TC-VAR-004, -008✅ Covered
URD-VAR-006TC-VAR-011✅ Covered
URD-VAR-007TC-VAR-009, -010✅ Covered
URD-VAR-008TC-VAR-012, -013, -022✅ Covered
URD-VAR-009⚠️ UOM storage built; no dedicated TC yet
URD-VAR-010⚠️ Bundles built; covered in dev docs, no module TC yet
URD-VAR-011TC-VAR-019⚠️ Planned (verifies not-implemented error)
URD-VAR-012⚠️ Planned (no TC)
URD-FAR-001TC-FAR-001, -002, TC-CON-010✅ Covered
URD-FAR-002TC-FAR-003, -004, TC-CON-011✅ Covered
URD-FAR-003TC-FAR-005, -006✅ Covered
URD-FAR-004TC-FAR-007, -008, -009, -016, -017✅ Covered
URD-FAR-005TC-FAR-010, -011✅ Covered
URD-FAR-006TC-FAR-012, -013, -014✅ Covered
URD-FAR-007TC-FAR-015✅ Covered
URD-PID-001TC-PID-001, -002, -007✅ Covered
URD-PID-002TC-PID-003✅ Covered
URD-PID-003TC-PID-004, -005, TC-CON-004✅ Covered
URD-PID-004TC-PID-006, -007, -008, TC-VAR-022✅ Covered
URD-CMP-001TC-CMP-001, -002, -003⚠️ In-progress (CRUD only)
URD-CMP-002TC-CMP-004⚠️ In-progress
URD-CMP-003TC-CMP-005⚠️ Planned (calc disabled)
URD-ACC-001TC-ACC-001, -002, -009, -011✅ Covered
URD-ACC-002TC-ACC-003, -004✅ Covered
URD-ACC-003TC-ACC-005, -006✅ Covered
URD-ACC-004TC-ACC-007, -008✅ Covered

Summary: all Must requirements covered. Gaps are limited to Planned / In-progress items (URD-PRD-019, URD-VAR-011/012, URD-CMP-003) and two built-but-untested Should items (URD-VAR-009 UOM, URD-VAR-010 bundles) flagged for future test authoring.

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.