---
id: TST-COM-CAT-092
title: Promotion Codes Verification
kind: api-lifecycle
product_area: commerce
module: catalog
revision: 1
status: draft
product_intent: proposed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
repository: services-commerce
files:
  - modules/promotions/tests/e2e/promotion-codes.e2e.spec.js
implements:
  - ATS-COM-CAT-015-01
  - ATS-COM-CAT-015-03
  - ATS-COM-CAT-015-04
  - ATS-COM-CAT-015-05
  - ATS-COM-CAT-015-07
  - ATS-COM-CAT-015-08
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 2
isolation: 'Suite-owned workspace keys and database fixtures, removed by its cleanup hooks.'
binding_evidence:
  - scenario: ATS-COM-CAT-015-01
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses “EARLY25”
      beside “early 25”, 409 code_taken
  - scenario: ATS-COM-CAT-015-01
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses a code
      another promotion of the tenant has, 409 code_taken
  - scenario: ATS-COM-CAT-015-01
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#keeps the code as
      typed for display and stores it normalised (J12)
  - scenario: ATS-COM-CAT-015-03
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses a window
      ending after the promotion’s, 400 window_exceeds_promotion
  - scenario: ATS-COM-CAT-015-03
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses a window
      starting before the promotion’s, 400 window_exceeds_promotion
  - scenario: ATS-COM-CAT-015-04
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#creates a
      full-width code as its normalised form, kept as typed for display, and refuses SPRING26 beside
      it (D-REC-12)
  - scenario: ATS-COM-CAT-015-05
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#makes a single-use
      code one use in all
  - scenario: ATS-COM-CAT-015-05
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses a
      single-use code with another limit, 400
  - scenario: ATS-COM-CAT-015-07
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses a limit
      below the uses made, 409 limit_below_uses
  - scenario: ATS-COM-CAT-015-08
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#disables an active
      code, enables a disabled one and revokes it
  - scenario: ATS-COM-CAT-015-08
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#refuses each
      operation from a state it does not move, 409 invalid_transition
  - scenario: ATS-COM-CAT-015-08
    source: >-
      services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#keeps a revoked
      code revoked: no operation moves it again
evidence:
  - 'services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js'
  - >-
    services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#Real: the composed
    handler, the routes, the mapper, the workflows, the persistence, the normalisation trigger and
    PostgreSQL.
  - >-
    services-commerce:modules/promotions/tests/e2e/promotion-codes.e2e.spec.js#Doubled: the signing
    key pair. Every call acts in a tenant of the spec's own, removed in `after`.
execution_constraints:
  - No execution is performed in this documentation back-fill.
verification_boundary: >-
  Bindings identify the existing assertions contributing to each scenario; several suites can
  jointly cover a compound scenario.
---

# Promotion Codes Verification

## Verification Boundary

The composed API handler runs locally with signed caller contexts and the integration database. Its route, mapping, permission and persistence assertions establish the local API boundary.

## What This Suite Proves

The promotion codes assertions contribute to the scenarios listed in the register. Each binding retains its exact source test anchor so a reviewer can distinguish an individual contribution from the complete scenario.

## What It Does Not Prove

The register records source inspection only. It establishes no run result, delivery qualification or Product approval.

## Real Dependencies and Test Doubles

PostgreSQL and the services called by the suite are real. External service ports, file storage and queues may use the fixtures declared by the suite and its support helpers.

## Must Not Be Doubled

Keep the asserted database constraints, transactions, service functions and execution contexts real. For API suites, preserve the dispatcher and permission enforcement.
