---
id: ATS-COM-CAT-009
scope: CAP-COM-CAT-009
product_area: commerce
module: catalog
revision: 2
status: proposed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-CAT-009-01
    title: 'Member downloads reject foreign, expired and unknown grants'
    level: api
    proves:
      - BR-CAP-COM-CAT-009-01
      - BR-CAP-COM-CAT-009-05
    preconditions: Two contacts and an expired grant exist
    steps: 'Use another contact’s grant, the expired grant and an unknown grant'
    expected: 'Access or expiry refusals apply, and the unknown grant is not found'
    negative: true
    data_needs: Entitlement grants
    bound_to:
      - TST-COM-CAT-012
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#refuses an expired grant 409
      and another member’s grant 403
    category: permission
    binding_evidence:
      - >-
        services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#refuses an expired grant
        409 and another member’s grant 403
      - >-
        services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#answers 404 for a grant of
        another kind, an unknown grant, and a file the product does not have
    step_evidence:
      - do: 'Use another contact’s grant, the expired grant and an unknown grant'
        provenance: test
        source: >-
          services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#refuses an expired grant
          409 and another member’s grant 403
    assertions:
      - expect: 'Access or expiry refusals apply, and the unknown grant is not found'
        provenance: test
        source: >-
          services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#refuses an expired grant
          409 and another member’s grant 403
  - id: ATS-COM-CAT-009-02
    title: Download retries preserve finite capacity
    level: api
    proves:
      - BR-CAP-COM-CAT-009-02
    preconditions: A finite grant and distinct request keys are available
    steps: 'Consume the allowed uses, repeat a key and request another new use'
    expected: Retries retain the prior remaining count and a new request after exhaustion fails
    negative: false
    data_needs: Entitlement grants
    bound_to:
      - TST-COM-CAT-012
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives the grant’s owner a
      signed link and consumes one use per Idempotency-Key (a retry costs nothing), until the grant
      is exhausted (409)
    category: invariant
    binding_evidence:
      - >-
        services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives the grant’s owner a
        signed link and consumes one use per Idempotency-Key (a retry costs nothing), until the
        grant is exhausted (409)
    step_evidence:
      - do: 'Consume the allowed uses, repeat a key and request another new use'
        provenance: test
        source: >-
          services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives the grant’s owner
          a signed link and consumes one use per Idempotency-Key (a retry costs nothing), until the
          grant is exhausted (409)
    assertions:
      - expect: Retries retain the prior remaining count and a new request after exhaustion fails
        provenance: test
        source: >-
          services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives the grant’s owner
          a signed link and consumes one use per Idempotency-Key (a retry costs nothing), until the
          grant is exhausted (409)
  - id: ATS-COM-CAT-009-03
    title: Console support preserves download capacity
    level: api
    proves:
      - BR-CAP-COM-CAT-009-04
    preconditions: A member has a limited grant
    steps: Request its file as console support
    expected: A signed link returns without consuming member usage
    negative: false
    data_needs: Entitlement grants
    bound_to:
      - TST-COM-CAT-012
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives a console user the
      link without consuming a use
    category: permission
    binding_evidence:
      - >-
        services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives a console user the
        link without consuming a use
    step_evidence:
      - do: Request its file as console support
        provenance: test
        source: >-
          services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives a console user the
          link without consuming a use
    assertions:
      - expect: A signed link returns without consuming member usage
        provenance: test
        source: >-
          services-commerce:modules/catalog/tests/e2e/downloads.e2e.spec.js#gives a console user the
          link without consuming a use
  - id: ATS-COM-CAT-009-04
    title: Download access follows the listing’s retained file
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-CAT-006-04
      - BR-CAP-COM-CAT-009-02
      - BR-CAP-COM-CAT-009-05
    preconditions: >-
      A buyer owns a finite download grant for digitally delivered merchandise with one retained
      private file.
    steps: >-
      Download the file, replace the listing’s file, then request the old file, the retained
      replacement and a repeated request key.
    expected: >-
      The detached file is not found, the replacement is available under the same grant and a
      repeated key does not consume another use.
    negative: false
    data_needs: 'Run-owned workspace, prepared file fixtures and independent fault injection at the handoff.'
    bound_to: []
    provenance: proposed
    source:
      - 'services-commerce:modules/catalog/services/downloads/downloads.ts:downloadFile'
      - >-
        rhythm-v2-docs:specs/commerce/catalog/design/workflows/WF-COM-CAT-008-download-an-entitled-file.md#WF-COM-CAT-008
    exercises:
      - CAP-COM-CAT-006
      - CAP-COM-CAT-009
    workflows:
      - WF-COM-CAT-008
    step_evidence:
      - do: >-
          Download the file, replace the listing’s file, then request the old file, the retained
          replacement and a repeated request key.
        provenance: proposed
        source:
          - 'services-commerce:modules/catalog/services/downloads/downloads.ts:downloadFile'
          - >-
            rhythm-v2-docs:specs/commerce/catalog/design/workflows/WF-COM-CAT-008-download-an-entitled-file.md#WF-COM-CAT-008
    assertions:
      - expect: >-
          The detached file is not found, the replacement is available under the same grant and a
          repeated key does not consume another use.
        provenance: proposed
        source:
          - 'services-commerce:modules/catalog/services/downloads/downloads.ts:downloadFile'
          - >-
            rhythm-v2-docs:specs/commerce/catalog/design/workflows/WF-COM-CAT-008-download-an-entitled-file.md#WF-COM-CAT-008
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-009-deliver-the-files-a-buyer-is-entitled-to.md#CAP-COM-CAT-009
  - >-
    rhythm-v2-docs:specs/commerce/catalog/design/workflows/WF-COM-CAT-008-download-an-entitled-file.md#WF-COM-CAT-008
product_intent: proposed
coverage:
  rule: 'gap: FND-COM-CAT-063'
  transition: 'gap: FND-COM-CAT-063'
  validation: 'gap: FND-COM-CAT-063'
  permission: covered
  edge: 'gap: FND-COM-CAT-063'
  failure: 'gap: FND-COM-CAT-063'
  boundary: 'gap: FND-COM-CAT-063'
  concurrency: 'gap: FND-COM-CAT-063'
  invariant: covered
  interaction: covered
coverage_notes:
  rule: >-
    No complete rule scenario is established by this back-fill; the finding records the missing
    proof.
  transition: >-
    No complete transition scenario is established by this back-fill; the finding records the
    missing proof.
  validation: >-
    No complete validation 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.
permission_coverage:
  - key: commerce.downloads.read
    coverage: 'gap: FND-COM-CAT-063'
    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-063'
---

# Retrieve purchased digital files: Capability Test Specification

## Coverage

| Rule | Proof Scenario or Gap |
|---|---|
| `BR-CAP-COM-CAT-009-01` | `ATS-COM-CAT-009-01` |
| `BR-CAP-COM-CAT-009-02` | `ATS-COM-CAT-009-02`, `ATS-COM-CAT-009-04` |
| `BR-CAP-COM-CAT-009-04` | `ATS-COM-CAT-009-03` |
| `BR-CAP-COM-CAT-009-05` | `ATS-COM-CAT-009-01`, `ATS-COM-CAT-009-04` |

## Interactions With Related Capabilities

The interaction boundary remains a recorded coverage gap until a complete scenario establishes the handoff. Download access follows the listing’s retained file.

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