---
id: ATS-COM-CAT-002
scope: CAP-COM-CAT-002
product_area: commerce
module: catalog
revision: 2
status: proposed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-CAT-002-01
    title: Resolution identifies each winning fallback
    level: api
    proves:
      - BR-CAP-COM-CAT-002-03
    preconditions: Workspace and events defaults reference different policies
    steps: 'Resolve an explicit policy, an events context and an empty context'
    expected: Each response identifies the selected policy and selection source
    negative: false
    data_needs: Two policies
    bound_to:
      - TST-COM-CAT-030
      - TST-COM-CAT-036
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves a
      context: the profile it names (explicit), else its application’s default, else the tenant
      default
    category: rule
    binding_evidence:
      - >-
        services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves a
        context: the profile it names (explicit), else its application’s default, else the tenant
        default
      - >-
        services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.queries.integration.spec.js#resolveOrderingProfile
        walks the hierarchy of 22 §3 and names the source
    step_evidence:
      - do: 'Resolve an explicit policy, an events context and an empty context'
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves a
          context: the profile it names (explicit), else its application’s default, else the tenant
          default
    assertions:
      - expect: Each response identifies the selected policy and selection source
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves a
          context: the profile it names (explicit), else its application’s default, else the tenant
          default
  - id: ATS-COM-CAT-002-02
    title: Resolution refuses an unknown policy
    level: api
    proves:
      - BR-CAP-COM-CAT-002-04
    preconditions: The requested policy is absent from the workspace
    steps: Request resolution by that policy reference
    expected: The request fails validation
    negative: true
    data_needs: none
    bound_to:
      - TST-COM-CAT-030
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#answers 400 to
      a context naming a profile the tenant does not have, and nothing for a tenant with no profile
      at all
    category: validation
    binding_evidence:
      - >-
        services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#answers 400
        to a context naming a profile the tenant does not have, and nothing for a tenant with no
        profile at all
    step_evidence:
      - do: Request resolution by that policy reference
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#answers
          400 to a context naming a profile the tenant does not have, and nothing for a tenant with
          no profile at all
    assertions:
      - expect: The request fails validation
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#answers
          400 to a context naming a profile the tenant does not have, and nothing for a tenant with
          no profile at all
  - id: ATS-COM-CAT-002-03
    title: Inactive defaults cannot replace the saved document
    level: api
    proves:
      - BR-CAP-COM-CAT-002-06
      - INV-DOM-COM-CAT-001-04
    preconditions: An inactive policy and existing defaults are available
    steps: Submit defaults referencing the inactive policy
    expected: The request fails and preserves existing defaults
    negative: true
    data_needs: none
    bound_to:
      - TST-COM-CAT-030
      - TST-COM-CAT-035
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#refuses a
      document naming an inactive or an unknown profile, 400, the document unchanged
    category: validation
    binding_evidence:
      - >-
        services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#refuses a
        document naming an inactive or an unknown profile, 400, the document unchanged
      - >-
        services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.integration.spec.js#refuses
        an unknown or an inactive profile anywhere in the document, 400, the document unchanged
    step_evidence:
      - do: Submit defaults referencing the inactive policy
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#refuses a
          document naming an inactive or an unknown profile, 400, the document unchanged
    assertions:
      - expect: The request fails and preserves existing defaults
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#refuses a
          document naming an inactive or an unknown profile, 400, the document unchanged
  - id: ATS-COM-CAT-002-04
    title: Read authority permits defaults and resolution reads
    level: api
    proves:
      - BR-CAP-COM-CAT-002-08
    preconditions: The caller has no write permission
    steps: Read defaults and resolve a policy
    expected: Both reads return results
    negative: false
    data_needs: Read-exclusively persona
    bound_to:
      - TST-COM-CAT-028
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/e2e/configuration-security.e2e.spec.js#lists and
      reads the ordering profiles, the defaults document and the resolution
    category: permission
    binding_evidence:
      - >-
        services-commerce:modules/configuration/tests/e2e/configuration-security.e2e.spec.js#lists
        and reads the ordering profiles, the defaults document and the resolution
    step_evidence:
      - do: Read defaults and resolve a policy
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/configuration-security.e2e.spec.js#lists
          and reads the ordering profiles, the defaults document and the resolution
    assertions:
      - expect: Both reads return results
        provenance: test
        source: >-
          services-commerce:modules/configuration/tests/e2e/configuration-security.e2e.spec.js#lists
          and reads the ordering profiles, the defaults document and the resolution
  - id: ATS-COM-CAT-002-05
    title: Checkout selection retains one governing policy
    level: api
    proves:
      - BR-CAP-COM-CAT-002-01
      - BR-CAP-COM-CAT-002-02
      - AS-JNY-COM-CAT-001-02
    preconditions: A store uses Main and an item context specifies Conference EUR
    steps: 'Open a store checkout, then a storeless checkout with the EUR item and add a Main item'
    expected: >-
      Selection uses the store or item context respectively; the conflicting item is refused with
      both policies identified
    negative: true
    data_needs: A participant answering a selling context
    bound_to: []
    provenance: proposed
    source: 'services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D9'
    category: interaction
    step_evidence:
      - do: 'Open a store checkout, then a storeless checkout with the EUR item and add a Main item'
        provenance: proposed
        source: 'services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D9'
    assertions:
      - expect: >-
          Selection uses the store or item context respectively; the conflicting item is refused
          with both policies identified
        provenance: proposed
        source: 'services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D9'
  - id: ATS-COM-CAT-002-06
    title: Changing the default changes fallback selection
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-CAT-001-09
      - BR-CAP-COM-CAT-002-03
    preconditions: Two active policies and no application default exist.
    steps: >-
      Resolve the fallback, transfer the workspace default, resolve again and attempt to disable the
      selected policy.
    expected: The new policy is selected and cannot be disabled while retained as default.
    negative: false
    data_needs: Run-owned workspace and records; fixed clock where dates are exercised.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.integration.spec.js#makes
        a second profile no default, and one stating is_tenant_default the default in place of the
        first, in one transaction
      - >-
        services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves a
        context: the profile it names (explicit), else its application’s default, else the tenant
        default
    exercises:
      - CAP-COM-CAT-001
      - CAP-COM-CAT-002
    workflows:
      - WF-COM-CAT-001
    step_evidence:
      - do: >-
          Resolve the fallback, transfer the workspace default, resolve again and attempt to disable
          the selected policy.
        provenance: proposed
        source:
          - >-
            services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.integration.spec.js#makes
            a second profile no default, and one stating is_tenant_default the default in place of
            the first, in one transaction
          - >-
            services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves
            a context: the profile it names (explicit), else its application’s default, else the
            tenant default
    assertions:
      - expect: The new policy is selected and cannot be disabled while retained as default.
        provenance: proposed
        source:
          - >-
            services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.integration.spec.js#makes
            a second profile no default, and one stating is_tenant_default the default in place of
            the first, in one transaction
          - >-
            services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#resolves
            a context: the profile it names (explicit), else its application’s default, else the
            tenant default
  - id: ATS-COM-CAT-002-07
    title: Store selection overrides item context without mixing policies
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-CAT-002-01
      - BR-CAP-COM-CAT-002-02
      - BR-CAP-COM-CAT-003-01
    preconditions: A store uses Main and an item context uses Conference EUR.
    steps: >-
      Open one checkout through the store and another without it; add an item resolving to Main to
      the EUR checkout.
    expected: >-
      The store checkout uses Main; the storeless checkout uses Conference EUR and refuses the
      conflicting item.
    negative: false
    data_needs: Run-owned workspace and records; fixed clock where dates are exercised.
    bound_to: []
    provenance: proposed
    source:
      - 'services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D9'
      - >-
        services-commerce:docs/milestones/plans/COMM-M1-plan.md#D9. Adopt the expanded
        ordering-profile selection order?
      - >-
        services-commerce:modules/configuration/tests/e2e/stores.e2e.spec.js#answers 400 to an
        ordering profile the tenant does not have, naming the property
    exercises:
      - CAP-COM-CAT-002
      - CAP-COM-CAT-003
    workflows: []
    step_evidence:
      - do: >-
          Open one checkout through the store and another without it; add an item resolving to Main
          to the EUR checkout.
        provenance: proposed
        source:
          - 'services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D9'
          - >-
            services-commerce:docs/milestones/plans/COMM-M1-plan.md#D9. Adopt the expanded
            ordering-profile selection order?
          - >-
            services-commerce:modules/configuration/tests/e2e/stores.e2e.spec.js#answers 400 to an
            ordering profile the tenant does not have, naming the property
    assertions:
      - expect: >-
          The store checkout uses Main; the storeless checkout uses Conference EUR and refuses the
          conflicting item.
        provenance: proposed
        source:
          - 'services-commerce:docs/milestones/COMM-M1-set-up-what-you-sell.md#D9'
          - >-
            services-commerce:docs/milestones/plans/COMM-M1-plan.md#D9. Adopt the expanded
            ordering-profile selection order?
          - >-
            services-commerce:modules/configuration/tests/e2e/stores.e2e.spec.js#answers 400 to an
            ordering profile the tenant does not have, naming the property
evidence:
  - 'Pinned service inputs: test sources in scenario bindings'
  - 'Pinned console inputs: console sources in scenario bindings'
  - >-
    rhythm-v2-docs:specs/commerce/catalog/planning/capabilities/CAP-COM-CAT-002-decide-which-checkout-policy-a-sale-follows.md#CAP-COM-CAT-002
  - >-
    rhythm-v2-docs:specs/commerce/catalog/design/workflows/WF-COM-CAT-001-save-a-checkout-policy-against-accounting-s.md#WF-COM-CAT-001
  - >-
    rhythm-v2-docs:specs/commerce/catalog/design/workflows/WF-COM-CAT-002-resolve-which-checkout-policy-a-sale-follows.md#WF-COM-CAT-002
product_intent: proposed
coverage:
  rule: covered
  transition: 'gap: FND-COM-CAT-056'
  validation: covered
  permission: covered
  edge: 'gap: FND-COM-CAT-056'
  failure: 'gap: FND-COM-CAT-056'
  boundary: 'gap: FND-COM-CAT-056'
  concurrency: 'gap: FND-COM-CAT-056'
  invariant: 'gap: FND-COM-CAT-056'
  interaction: covered
coverage_notes:
  transition: >-
    No complete transition scenario is established by this back-fill; the finding records the
    missing proof.
  edge: >-
    No complete edge scenario is established by this back-fill; the finding records the missing
    proof.
  failure: >-
    No complete failure scenario is established by this back-fill; the finding records the missing
    proof.
  boundary: >-
    No complete boundary scenario is established by this back-fill; the finding records the missing
    proof.
  concurrency: Concurrent execution has no complete scenario; sequential retry is insufficient proof.
  invariant: >-
    No complete invariant scenario is established by this back-fill; the finding records the missing
    proof.
permission_coverage:
  - key: commerce.ordering-profiles.read
    coverage: 'gap: FND-COM-CAT-056'
    reason: >-
      Existing permission examples cover selected personas, not the independent allow and deny
      matrix for every named key.
    provenance: unknown
    source:
      - 'rhythm-v2-docs:specs/commerce/catalog/FINDINGS.md#FND-COM-CAT-056'
  - key: commerce.ordering-profiles.update
    coverage: 'gap: FND-COM-CAT-056'
    reason: >-
      Existing permission examples cover selected personas, not the independent allow and deny
      matrix for every named key.
    provenance: unknown
    source:
      - 'rhythm-v2-docs:specs/commerce/catalog/FINDINGS.md#FND-COM-CAT-056'
---

# Select the policy governing a sale: Capability Test Specification

## Coverage

| Rule | Proof Scenario or Gap |
|---|---|
| `BR-CAP-COM-CAT-002-01` | `ATS-COM-CAT-002-05`, `ATS-COM-CAT-002-07` |
| `BR-CAP-COM-CAT-002-02` | `ATS-COM-CAT-002-05`, `ATS-COM-CAT-002-07` |
| `BR-CAP-COM-CAT-002-03` | `ATS-COM-CAT-002-01`, `ATS-COM-CAT-002-06` |
| `BR-CAP-COM-CAT-002-04` | `ATS-COM-CAT-002-02` |
| `BR-CAP-COM-CAT-002-06` | `ATS-COM-CAT-002-03` |
| `BR-CAP-COM-CAT-002-08` | `ATS-COM-CAT-002-04` |

## Interactions With Related Capabilities

Checkout selection retains one governing policy. Changing the default changes fallback selection. Store selection overrides item context without mixing policies.

Coverage describes specified proof. A binding names the existing assertions that contribute to it; proposed designs remain unexecuted.
