---
id: ATS-CRM-REG-006
scope: CAP-CRM-REG-006
product_area: crm
module: regions
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-REG-006-01
    title: Ordering resolves overlapping criteria
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-01
    preconditions: Two enabled rules both cover the address.
    steps: Evaluate that address.
    expected: The earlier rule’s target wins.
    negative: false
    data_needs: Prepared geographic coverage examples.
    bound_to:
      - TST-CRM-REG-065
      - TST-CRM-REG-058
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers the
      first rule that matches when several would
    category: rule
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers the
        first rule that matches when several would
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#incomplete
        addresses and the matcher’s own comparisons › answers the first rule in order when two match
        (postal code before state)
  - id: ATS-CRM-REG-006-02
    title: Fallback is deferred and the final enabled fallback wins
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-02
    preconditions: A fallback precedes geographic coverage and another fallback appears later.
    steps: Evaluate a covered and an uncovered address.
    expected: The geographic target wins for coverage and the later enabled fallback wins otherwise.
    negative: false
    data_needs: Prepared geographic coverage examples.
    bound_to:
      - TST-CRM-REG-065
      - TST-CRM-REG-057
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › tries the
      rest-of-the-world rule last wherever it sits in the order
    category: edge
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › tries the
        rest-of-the-world rule last wherever it sits in the order
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers the
        rest-of-the-world region when nothing else matches
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers the
        last rest-of-the-world rule when the tenant has several
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#the
        rest of the world rule › gives an address no other rule matched the rest of the world region
  - id: ATS-CRM-REG-006-03
    title: Disabled coverage contributes no result
    level: api
    proves:
      - BR-CAP-CRM-REG-006-03
    preconditions: 'A disabled match precedes enabled coverage, and another policy has only a disabled fallback.'
    steps: Assign addressed contacts with each policy.
    expected: The enabled coverage wins in the first policy and no region results from the second.
    negative: false
    data_needs: Two independently prepared geographic policies.
    bound_to:
      - TST-CRM-REG-057
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
      rule staff turned off › skips the disabled rule and answers the next rule that matches
    category: edge
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
        rule staff turned off › skips the disabled rule and answers the next rule that matches
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
        rule staff turned off › gives no region when only a disabled rest of the world rule is left,
        because a disabled rule is no answer
  - id: ATS-CRM-REG-006-04
    title: Text intervals include their endpoints
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-04
    preconditions: Postal coverage spans the configured five-digit interval.
    steps: 'Evaluate both endpoints, an interior ZIP+4 and the next uncovered code.'
    expected: The endpoints and interior value match while the uncovered code does not.
    negative: true
    data_needs: Postal inputs spanning the relevant boundary cases.
    bound_to:
      - TST-CRM-REG-065
      - TST-CRM-REG-064
      - TST-CRM-REG-058
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › compares
      postal codes as strings, so a ZIP+4 code inside the range matches
    category: boundary
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › compares
        postal codes as strings, so a ZIP+4 code inside the range matches
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › does not
        match a postal code just past the end of the range
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js#Postal
        Code Ranges › should match the beginning of the range
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js#Postal
        Code Ranges › should match the end of the range
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#incomplete
        addresses and the matcher’s own comparisons › matches a ZIP+4 postal code inside a five-digit
        range
  - id: ATS-CRM-REG-006-05
    title: Postal-country restrictions distinguish otherwise equal codes
    level: api
    proves:
      - BR-CAP-CRM-REG-006-05
    preconditions: Postal coverage is restricted to the United States.
    steps: 'Evaluate the same code with US, Canadian and omitted country values.'
    expected: US and omitted country match; Canada does not.
    negative: true
    data_needs: Three contrasting address inputs.
    bound_to:
      - TST-CRM-REG-057
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
      postal code rule confined to a country › matches an address in the country the rule names
    category: boundary
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
        postal code rule confined to a country › matches an address in the country the rule names
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
        postal code rule confined to a country › refuses the same postal code in another country
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#a
        postal code rule confined to a country › counts an address with no country as US, so a rule
        confined to US matches it
  - id: ATS-CRM-REG-006-06
    title: State matching preserves case sensitivity
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-06
    preconditions: A rule lists an uppercase state code.
    steps: Evaluate the upper- and lowercase versions.
    expected: Only the uppercase value matches.
    negative: true
    data_needs: Two contrasting address inputs.
    bound_to:
      - TST-CRM-REG-065
      - TST-CRM-REG-064
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › matches states
      exactly, so a lower-case state is not the upper-case one
    category: edge
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › matches
        states exactly, so a lower-case state is not the upper-case one
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js#States
        › should the match if the state matches
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js#States
        › should NOT match if the state does not match
  - id: ATS-CRM-REG-006-07
    title: Country matching supplies the legacy default
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-07
    preconditions: Coverage includes the United States in lowercase.
    steps: 'Evaluate uppercase, lowercase, blank and missing country values.'
    expected: All four inputs match US coverage.
    negative: false
    data_needs: Four address examples for the comparison.
    bound_to:
      - TST-CRM-REG-065
      - TST-CRM-REG-064
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › matches the
      country whatever the case of the address or the rule
    category: edge
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › matches the
        country whatever the case of the address or the rule
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › counts an
        address with no country as US
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js#Countries
        › should the match if the country is null
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js#Countries
        › should the match if the country is blank
  - id: ATS-CRM-REG-006-08
    title: Uncovered addresses can remain unplaced
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-09
    preconditions: The policy contains no fallback.
    steps: Evaluate an address outside its geographic rules.
    expected: The matcher returns no region.
    negative: false
    data_needs: Prepared geographic coverage examples.
    bound_to:
      - TST-CRM-REG-065
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers no
      region when nothing matches and there is no rest-of-the-world rule
    category: rule
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers no
        region when nothing matches and there is no rest-of-the-world rule
  - id: ATS-CRM-REG-006-09
    title: An absent address cannot use fallback
    level: unit
    proves:
      - BR-CAP-CRM-REG-006-10
    preconditions: The policy includes a fallback.
    steps: Evaluate absent and entirely empty address inputs.
    expected: Neither input receives a region.
    negative: false
    data_needs: Prepared geographic coverage examples.
    bound_to:
      - TST-CRM-REG-065
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers no
      region for no address even with a rest-of-the-world rule
    category: edge
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers no
        region for no address even with a rest-of-the-world rule
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#region_for_address › answers no
        region for an address whose every field is empty
  - id: ATS-CRM-REG-006-10
    title: Saved matching is shared by preview and placement
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-REG-006-01
      - BR-CAP-CRM-REG-007-01
      - BR-CAP-CRM-REG-008-01
    preconditions: Two active regions have overlapping coverage and automatic placement is enabled.
    steps: >-
      Save the geographic policy, preview an address, create a contact with that deciding address and
      deliver assignment; reverse the coverage order and repeat with a new contact.
    expected: >-
      Each preview and corresponding new placement select the same first matching target in the saved
      order.
    negative: false
    data_needs: Two active regions have overlapping coverage and automatic placement is enabled.
    bound_to: []
    provenance: proposed
    source: WF-CRM-REG-001
    exercises:
      - CAP-CRM-REG-004
      - CAP-CRM-REG-005
      - CAP-CRM-REG-006
      - CAP-CRM-REG-007
      - CAP-CRM-REG-008
  - id: ATS-CRM-REG-006-11
    title: Unsupported criteria fail instead of choosing a target
    category: failure
    level: unit
    proves:
      - BR-CAP-CRM-REG-004-01
    preconditions: A direct matcher caller supplies a rule kind outside the supported set.
    steps: Evaluate a nonempty address against that rule.
    expected: Evaluation throws an unsupported-kind error and supplies no regional result.
    negative: true
    data_needs: A direct matcher caller supplies a rule kind outside the supported set.
    bound_to:
      - TST-CRM-REG-065
    provenance: test
    source: >-
      services-crm:modules/regions/tests/unit/region-matching.spec.js#refuses a rule type it does not
      know
    test_assertions:
      - >-
        services-crm:modules/regions/tests/unit/region-matching.spec.js#refuses a rule type it does not
        know
  - id: ATS-CRM-REG-006-12
    title: Nongeographic recognized input establishes fallback eligibility
    category: edge
    level: api
    proves:
      - BR-CAP-CRM-REG-006-11
    preconditions: A saved policy has one geographic rule and one enabled fallback.
    steps: >-
      Evaluate an address containing only a street line, then an address containing only unrelated
      properties and finally an empty address.
    expected: The street-only input receives fallback; unrelated-only and empty input receive no match.
    negative: false
    data_needs: A saved policy has one geographic rule and one enabled fallback.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/regions/services/region-assignment/region-matching.ts:hasAddress,
      geographicAddressOf, matchRegionRule
  - id: ATS-CRM-REG-006-13
    title: A saved reversed interval supplies no match
    category: boundary
    level: browser
    proves:
      - BR-CAP-CRM-REG-006-12
    preconditions: A saved postal rule has its end lexically before its start and no fallback is enabled.
    steps: Save that interval and preview a code between its reversed bounds.
    expected: Saving succeeds and preview returns no regional match.
    negative: false
    data_needs: A saved postal rule has its end lexically before its start and no fallback is enabled.
    bound_to:
      - TST-CRM-REG-007
    provenance: test
    source: 'react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0358.spec.ts#CRM-ACC-0358'
    test_assertions:
      - 'react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0358.spec.ts#CRM-ACC-0358'
  - id: ATS-CRM-REG-006-14
    title: Save-time geographic cleaning feeds matching
    category: rule
    level: api
    proves:
      - BR-CAP-CRM-REG-006-08
    preconditions: Enabled state and country rules target local regions.
    steps: >-
      Save a contact address with its state written as a supported full name, deliver assignment and
      repeat with a supported full country name.
    expected: The cleaned address codes select the expected geographic targets.
    negative: false
    data_needs: Enabled state and country rules target local regions.
    bound_to:
      - TST-CRM-REG-058
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#normalized
      address variants (the save-time cleaning, docs/migrations/contact-and-organization-cleaning/) ›
      matches a state rule from the state written out in full
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#matches
        a state rule from the state written out in full
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#matches
        a country rule from the country written as its name
  - id: ATS-CRM-REG-006-15
    title: Retired targets remain consistent across preview and traversal
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-REG-002-08
      - BR-CAP-CRM-REG-006-01
      - BR-CAP-CRM-REG-011-05
    preconditions: >-
      An enabled rule targets a retired definition and an eligible addressed contact has an older
      placement.
    steps: >-
      Preview the contact’s deciding address, run recalculation and read its final placement and the
      retained definition.
    expected: >-
      Preview and recalculation both select the enabled rule’s retired target while its definition
      remains readable.
    negative: false
    data_needs: >-
      An enabled rule targets a retired definition and an eligible addressed contact has an older
      placement.
    bound_to: []
    provenance: proposed
    source: ADR-CRM-REG-005
    exercises:
      - CAP-CRM-REG-002
      - CAP-CRM-REG-006
      - CAP-CRM-REG-007
      - CAP-CRM-REG-011
evidence:
  - >-
    services-crm: Examined the pinned regional implementation, its declared constraints and the
    supporting records.
  - 'react-console: Examined the pinned regional configuration surfaces and their available test evidence.'
  - 'services-crm:modules/regions/tests/unit/region-matching.spec.js'
  - >-
    services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js
  - >-
    services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js
  - >-
    services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/calculate-region.unit.spec.js
coverage:
  rule: covered
  transition: not-applicable
  validation: 'gap: FND-CRM-REG-051'
  permission: not-applicable
  edge: covered
  failure: covered
  boundary: covered
  concurrency: 'gap: FND-CRM-REG-051'
  invariant: 'gap: FND-CRM-REG-051'
  interaction: covered
coverage_notes:
  transition: This capability computes or previews a result and owns no persisted state transition.
  permission: >-
    The in-process matcher declares no independent action key; API and record callers enforce their own
    authority.
---

# Determine an address’s geographic region: Capability Test Specification

## Coverage

A covered category has an authored proof; execution and remaining variants are tracked separately.

| Rule | Proved By |
|---|---|
| `BR-CAP-CRM-REG-006-01` | `ATS-CRM-REG-006-01`, `ATS-CRM-REG-006-10`, `ATS-CRM-REG-006-15` |
| `BR-CAP-CRM-REG-006-02` | `ATS-CRM-REG-006-02` |
| `BR-CAP-CRM-REG-006-03` | `ATS-CRM-REG-006-03` |
| `BR-CAP-CRM-REG-006-04` | `ATS-CRM-REG-006-04` |
| `BR-CAP-CRM-REG-006-05` | `ATS-CRM-REG-006-05` |
| `BR-CAP-CRM-REG-006-06` | `ATS-CRM-REG-006-06` |
| `BR-CAP-CRM-REG-006-07` | `ATS-CRM-REG-006-07` |
| `BR-CAP-CRM-REG-006-08` | `ATS-CRM-REG-006-14` |
| `BR-CAP-CRM-REG-006-09` | `ATS-CRM-REG-006-08` |
| `BR-CAP-CRM-REG-006-10` | `ATS-CRM-REG-006-09` |
| `BR-CAP-CRM-REG-006-11` | `ATS-CRM-REG-006-12` |
| `BR-CAP-CRM-REG-006-12` | `ATS-CRM-REG-006-13` |

## Interactions With Related Capabilities

Saved matching is shared by preview and placement. The interaction scenario connects retire regions while preserving their references, build the geographic assignment policy, check an address against the saved policy, keep placements aligned with address changes, apply the current policy across existing records with this capability. Cross-workflow expectations are proposed where no executable binding is present.
