---
id: ATS-MBR-MEM-002
scope: CAP-MBR-MEM-002
product_area: membership
module: memberships
revision: 1
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-MBR-MEM-002-01
    title: Refuse direct additions to organizational child memberships
    level: api
    proves:
      - BR-CAP-MBR-MEM-002-01
    preconditions: A corporate principal membership has flow-down and assigned children.
    steps: Attempt to add a staff term directly to each organizational child membership.
    expected: 'Each request is rejected as a direct child write, and no additional term is saved.'
    negative: true
    data_needs: 'Corporate, flow-down and assigned membership fixtures with their source parent.'
    bound_to: []
    provenance: proposed
    source: 'services-membership:modules/memberships/services/operations/staff-operations.ts:refuseChild'
  - id: ATS-MBR-MEM-002-02
    title: Compute the next period when dates are omitted
    level: api
    proves:
      - BR-CAP-MBR-MEM-002-02
    preconditions: An existing membership has a dated effective term and a package that continues from its end.
    steps: Add another term under the continuing package without supplying start or end dates.
    expected: The new period begins immediately after the earlier end and follows the package’s duration.
    negative: false
    data_needs: An annual continuing package and a membership with a known term end.
    bound_to:
      - >-
        services-membership:modules/memberships/tests/integration/services/staff-operations.integration.spec.ts#adds
        a renewal continuing the latest term when no dates are given
      - >-
        services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#commits the Alumni term for
        the next term, continuing from the Student term’s end
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/integration/services/staff-operations.integration.spec.ts#adds
      a renewal continuing the latest term when no dates are given
  - id: ATS-MBR-MEM-002-03
    title: Classify additions by their actual gaps
    level: unit
    proves:
      - BR-CAP-MBR-MEM-002-03
    preconditions: >-
      Classification inputs include a first term, a contiguous term, a gap inside the window, a gap outside it
      and a package without a window.
    steps: Classify each supplied period relative to its predecessor.
    expected: 'The results are enrolment, renewal, reinstatement, rejoin and rejoin, in that order.'
    negative: false
    data_needs: Local dates and reinstatement settings for each classification boundary.
    bound_to:
      - >-
        services-membership:modules/memberships/tests/unit/term-events.spec.ts#is an enrolment for the first
        effective term
      - >-
        services-membership:modules/memberships/tests/unit/term-events.spec.ts#is a renewal for a term
        starting the day after the latest ended
      - >-
        services-membership:modules/memberships/tests/unit/term-events.spec.ts#is a reinstatement for a term
        starting within the reinstatement window
      - >-
        services-membership:modules/memberships/tests/unit/term-events.spec.ts#is a rejoin for a term starting
        after the reinstatement window (scenario 4: 437 days)
      - >-
        services-membership:modules/memberships/tests/unit/term-events.spec.ts#is a rejoin for any gap when
        the package has no reinstatement window
      - >-
        services-membership:tests/acceptance/memberships/MBR-ACC-0169.acceptance.ts#MBR-ACC-0169: A dropped
        member who comes back is continued inside the reinstatement window and started afresh outside it, and
        the event log says renewed, reinstated or rejoined by the gap
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/unit/term-events.spec.ts#is an enrolment for the first
      effective term
  - id: ATS-MBR-MEM-002-04
    title: Retain original joining history across a long interruption
    level: api
    proves:
      - BR-CAP-MBR-MEM-002-04
    preconditions: 'Sam has an expired, dropped term and a program with a 60-day continuity allowance.'
    steps: Record his return after a 437-day gap and inspect the resulting membership.
    expected: The original join date remains recorded and continuity contains two episodes.
    negative: false
    data_needs: 'Sam’s original period, drop reason and returning period.'
    bound_to:
      - >-
        services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#keeps the original join date and
        restarts continuity at the rejoin (a gap of 437 days is more than 60)
      - 'services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#answers two continuity episodes'
    provenance: test
    source: >-
      services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#keeps the original join date and restarts
      continuity at the rejoin (a gap of 437 days is more than 60)
  - id: ATS-MBR-MEM-002-05
    title: Keep the earlier type until a future renewal begins
    level: api
    proves:
      - BR-CAP-MBR-MEM-002-05
    preconditions: Maria has a Student period followed by an Alumni renewal beginning on 1 July 2027.
    steps: Inspect the original term and read membership on 30 June and 1 July 2027.
    expected: The original Student term is unchanged; the date-specific types are Student and Alumni respectively.
    negative: false
    data_needs: Student and Alumni types and their annual packages.
    bound_to:
      - >-
        services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#leaves the Student term
        untouched and current today, with the renewal recorded as renewed
      - >-
        services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#answers Student as of 30 June
        2027
      - >-
        services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#answers Alumni as of 1 July
        2027
    provenance: test
    source: >-
      services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#leaves the Student term
      untouched and current today, with the renewal recorded as renewed
  - id: ATS-MBR-MEM-002-06
    title: Reject a caller without authority to add terms
    level: api
    proves:
      - BR-CAP-MBR-MEM-002-08
    preconditions: The caller can read memberships but lacks permission to create terms.
    steps: Submit a further-term request using the restricted caller.
    expected: The API returns a forbidden response.
    negative: true
    data_needs: A readable membership and a caller without term-creation authority.
    bound_to:
      - >-
        services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#refuses a term from a caller
        without membership.terms.create
    provenance: test
    source: >-
      services-membership:tests/e2e/s01-early-renewal-type-change.e2e.spec.ts#refuses a term from a caller
      without membership.terms.create
evidence:
  - >-
    services-membership at 5994c270e8a37a30f848e99ba5b5ee6b87c08893: reviewed staff operations, term-event
    classification, staff integration tests, early-renewal and lapse/rejoin API suites, and the reinstatement
    acceptance suite.
---

# Extend an existing membership through a staff term: Acceptance Test Set

## Coverage

| Rule | Proved by |
|---|---|
| `BR-CAP-MBR-MEM-002-01` | `ATS-MBR-MEM-002-01` |
| `BR-CAP-MBR-MEM-002-02` | `ATS-MBR-MEM-002-02` |
| `BR-CAP-MBR-MEM-002-03` | `ATS-MBR-MEM-002-03` |
| `BR-CAP-MBR-MEM-002-04` | `ATS-MBR-MEM-002-04` |
| `BR-CAP-MBR-MEM-002-05` | `ATS-MBR-MEM-002-05` |
| `BR-CAP-MBR-MEM-002-06` | no scenario: `FND-MBR-MEM-008` |
| `BR-CAP-MBR-MEM-002-07` | no scenario: `FND-MBR-MEM-009` |
| `BR-CAP-MBR-MEM-002-08` | `ATS-MBR-MEM-002-06` |
