Skip to content

ATS-MBR-MEM-005Determine membership standing and refresh list status: Capability Test Specification

Markdown

ATS-MBR-MEM-005

Determine membership standing and refresh list status: Capability Test Specification

Markdown
  • DocumentProposed

KindAcceptance test setProduct areaMembershipModuleMemberships, Applications and Membership BillingRevision2

Read atservices-membership 5994c270react-console baf6dae3

Coverage

  • Rule gap: FND-MBR-MEM-087
  • Transition gap: FND-MBR-MEM-087
  • Validation covered
  • Permission gap: FND-MBR-MEM-087
  • Edge gap: FND-MBR-MEM-087
  • Failure covered
  • Boundary covered
  • Concurrency gap: FND-MBR-MEM-087
  • Invariant gap: FND-MBR-MEM-087
  • Interaction covered

Test Scenarios

12 scenarios proving CAP-MBR-MEM-005; 9 bound to an existing test.

01 Read standing across expiry and returnboundaryapitest
Proves
BR-CAP-MBR-MEM-005-01
Preconditions
Sam has coverage separated by a lapse and a returning term.
Steps
[ { "do": "Read Sam’s standing on dates during grace, during lapse and after his return.", "expect": "Grace follows expiry, lapse follows the 60-day allowance, and return coverage is active.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam grace, lapsed, then active across the lapse and rejoin (scenario 4)", "services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam lapsed, not a member, on 2024-01-31 and active on 2024-12-31 in memberships_as_of", "services-membership:tests/e2e/s04-lapse-and-rejoin.e2e.spec.ts#answers grace the day after the term ended and lapsed once the 60 days are over" ] } ]
Expected
Grace follows expiry, lapse follows the 60-day allowance, and return coverage is active.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam grace, lapsed, then active across the lapse and rejoin (scenario 4)
02 Distinguish the full range of membership standingruleapitest
Proves
BR-CAP-MBR-MEM-005-02
Preconditions
Fixtures include empty, pending, future, current, non-benefit, grace, lapsed and suspended memberships.
Steps
[ { "do": "Inspect each fixture’s derived standing and compare the non-benefit type’s result.", "expect": "The fixtures return their expected standing, including active without benefits for the non-benefit type.", "provenance": "test", "source": [ "services-membership:tests/acceptance/memberships/MBR-ACC-0179.acceptance.ts#MBR-ACC-0179: Every status the engine can answer, from the terms and the type's or program's grace: none, pending, future, active, active without benefits, grace, lapsed and suspended, with the same answer from the SQL twins" ] } ]
Expected
The fixtures return their expected standing, including active without benefits for the non-benefit type.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:tests/acceptance/memberships/MBR-ACC-0179.acceptance.ts#MBR-ACC-0179: Every status the engine can answer, from the terms and the type's or program's grace: none, pending, future, active, active without benefits, grace, lapsed and suspended, with the same answer from the SQL twins
03 Read current truth despite a stale cacheinvariantapitest
Proves
BR-CAP-MBR-MEM-005-03
Preconditions
The clock has crossed expiry while saved status still reflects an earlier date.
Steps
[ { "do": "Read the record before refreshing, then compare cached-status and current-status lists.", "expect": "The record reflects expiry before a sweep; cached filtering can lag behind current filtering.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#answers the right status on each side of the expiry before any sweep runs (the resolver needs none)", "services-membership:tests/acceptance/memberships/MBR-ACC-0178.acceptance.ts#MBR-ACC-0178: When the nightly sweep is missed the cached status lies but the record's status does not, lists filtered by the cache disagree with lists filtered by today's status, and only a catch-up repairs it" ] } ]
Expected
The record reflects expiry before a sweep; cached filtering can lag behind current filtering.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#answers the right status on each side of the expiry before any sweep runs (the resolver needs none)
04 Refresh the memberships at a normal nightly boundarytransitionapitest
Proves
BR-CAP-MBR-MEM-005-04
Preconditions
The previous sweep ran yesterday and one membership reaches an expiry boundary tonight.
Steps
[ { "do": "Run the boundary sweep and inspect the examined count and refreshed status.", "expect": "The boundary member is examined and refreshed to grace while mid-period memberships are omitted.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#examines only the memberships with a term at a boundary", "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#moves the cache to grace at the expiry boundary and records expired_detected" ] } ]
Expected
The boundary member is examined and refreshed to grace while mid-period memberships are omitted.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#examines only the memberships with a term at a boundary
05 Record actual expiry and lapse dates oncetransitionapitest
Proves
BR-CAP-MBR-MEM-005-05
Preconditions
A dated period crosses expiry and grace-end boundaries, including a delayed sweep.
Steps
[ { "do": "Sweep through expiry and repeat the day, then discover a lapse after its boundary.", "expect": "Expiry retains the day after the term end; late lapse retains the day after grace, without duplicate detections.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records lapsed_detected effective the day after grace ended, even when found late", "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#moves the cache to grace at the expiry boundary and records expired_detected", "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records nothing twice when the same night is swept again" ] } ]
Expected
Expiry retains the day after the term end; late lapse retains the day after grace, without duplicate detections.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records lapsed_detected effective the day after grace ended, even when found late
06 Catch up over the workspace after a missed runfailureapitest
Proves
BR-CAP-MBR-MEM-005-06
Preconditions
The previous recorded run predates yesterday.
Steps
[ { "do": "Run the next sweep and inspect its mode and every membership examined.", "expect": "Catch-up examines all workspace memberships.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#catches up after a missed night, recomputing every membership" ] } ]
Expected
Catch-up examines all workspace memberships.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#catches up after a missed night, recomputing every membership
07 Repeat a sweep without duplicate detectionsinvariantapitest
Proves
BR-CAP-MBR-MEM-005-07
Preconditions
An administrator has run today’s sweep once.
Steps
[ { "do": "Repeat today’s on-demand sweep and inspect detection counts.", "expect": "The repeat adds no new detections.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records nothing twice when the same night is swept again", "services-membership:tests/acceptance/memberships/MBR-ACC-0177.acceptance.ts#MBR-ACC-0177: An administrator runs the status sweep by hand: the first run catches up over every membership, later runs look only at today's boundaries, nothing is detected twice, and a cache-only change leaves no visible history" ] } ]
Expected
The repeat adds no new detections.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records nothing twice when the same night is swept again
08 Inspect joining history and continuity episodesinvariantapitest
Proves
BR-CAP-MBR-MEM-005-09
Preconditions
Sam’s returning term follows a gap longer than the continuity allowance.
Steps
[ { "do": "Read the original join date and episode periods after the returning term.", "expect": "The original join date is retained and two continuity episodes are returned.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam two continuity episodes (scenario 4)", "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)" ] } ]
Expected
The original join date is retained and two continuity episodes are returned.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam two continuity episodes (scenario 4)
09 Filter and page membership lists without duplicate unit matchesvalidationapitest
Proves
BR-CAP-MBR-MEM-005-10
Preconditions
A member belongs to multiple chapters under the same ancestor, with status and pagination fixtures.
Steps
[ { "do": "List through ancestor and chapter filters, compare current and saved status, and exercise paging and malformed filters.", "expect": "Each matching membership appears once per result set; paging follows id order and invalid filters are rejected by name.", "provenance": "test", "source": [ "services-membership:modules/memberships/tests/integration/services/affiliations.integration.spec.ts#lists a member of two chapters once under their zone and region, and under each chapter", "services-membership:tests/acceptance/memberships/MBR-ACC-0185.acceptance.ts#MBR-ACC-0185: Lists page by id in creation order with an opaque cursor, cap the page at 500, refuse a malformed limit, cursor, status, flag or date by name, and never silently ignore a parameter", "services-membership:tests/acceptance/memberships/MBR-ACC-0178.acceptance.ts#MBR-ACC-0178: When the nightly sweep is missed the cached status lies but the record's status does not, lists filtered by the cache disagree with lists filtered by today's status, and only a catch-up repairs it" ] } ]
Expected
Each matching membership appears once per result set; paging follows id order and invalid filters are rejected by name.
Data
Dated memberships, program and type settings, and the controlled clock or listing fixtures relevant to this case.
Bound to
Source
services-membership:modules/memberships/tests/integration/services/affiliations.integration.spec.ts#lists a member of two chapters once under their zone and region, and under each chapter
10 Apply grace scope on the resolved membership dateinteractionapiproposed
Proves
BR-CAP-MBR-MEM-005-01 BR-CAP-MBR-MEM-015-05
Preconditions
An officer reaches a chapter whose member has just expired.
Steps
[ { "do": "Read and list the member with grace scope disabled and enabled, then move beyond the grace end.", "expect": "Enabled grace includes the member during grace; the member leaves that reach after grace ends.", "provenance": "proposed", "source": [ "services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam grace, lapsed, then active across the lapse and rejoin (scenario 4)", "services-membership:modules/memberships/tests/unit/unit-scope.spec.ts#leaves a member in grace out when the roster rule excludes grace" ] } ]
Expected
Enabled grace includes the member during grace; the member leaves that reach after grace ends.
Data
An isolated workspace with the specified membership, package, chapter and partner-port fixtures.
Source
services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam grace, lapsed, then active across the lapse and rejoin (scenario 4),services-membership:modules/memberships/tests/unit/unit-scope.spec.ts#leaves a member in grace out when the roster rule excludes grace
11 Freeze resolved standing at month endinteractionapiproposed
Proves
BR-CAP-MBR-MEM-005-01 BR-CAP-MBR-MEM-019-02
Preconditions
A member expires near month end and the status cache is stale.
Steps
[ { "do": "Generate the monthly snapshot and compare its member row with the resolver at month end.", "expect": "The row has the month-end standing rather than the stale cached value.", "provenance": "proposed", "source": [ "services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam grace, lapsed, then active across the lapse and rejoin (scenario 4)", "services-membership:modules/snapshots/tests/integration/snapshot-pipeline.integration.spec.ts#plans September’s first version for the tenant, once" ] } ]
Expected
The row has the month-end standing rather than the stale cached value.
Data
An isolated workspace with the specified membership, package, chapter and partner-port fixtures.
Source
services-membership:modules/memberships/tests/integration/db/membership-functions.integration.spec.ts#answers Sam grace, lapsed, then active across the lapse and rejoin (scenario 4),services-membership:modules/snapshots/tests/integration/snapshot-pipeline.integration.spec.ts#plans September’s first version for the tenant, once
12 Publish one lapse event through repeated sweepsinteractionapiproposed
Proves
BR-CAP-MBR-MEM-005-05 BR-CAP-MBR-MEM-020-03
Preconditions
A term has passed its final grace day without renewed coverage.
Steps
[ { "do": "Run the status sweep after the lapse boundary, then repeat the same sweep.", "expect": "The saved lapse detection and termination event retain the original last covered day and are not duplicated.", "provenance": "proposed", "source": [ "services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records lapsed_detected effective the day after grace ended, even when found late", "services-membership:modules/events/tests/integration/business-events.integration.spec.ts#states one membership.term.terminated for a staff termination, with the person’s contact_id and the last day of rights" ] } ]
Expected
The saved lapse detection and termination event retain the original last covered day and are not duplicated.
Data
An isolated workspace with the specified membership, package, chapter and partner-port fixtures.
Source
services-membership:modules/memberships/tests/integration/services/status-sweep.integration.spec.ts#records lapsed_detected effective the day after grace ended, even when found late,services-membership:modules/events/tests/integration/business-events.integration.spec.ts#states one membership.term.terminated for a staff termination, with the person’s contact_id and the last day of rights

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.