Skip to main content
Version: Next

STD: Specimen Type Management (SPECIMEN)

Version: v3.1.0 Status: Draft SRS Source: docusaurus/docs/srs/kitcfg-specimens.md Domain: SPECIMEN


Overview

This document specifies tests for the Specimen Type Management domain, which covers specimen type CRUD, target name suffix-to-specimen mapping, and automatic specimen derivation during runfile import. All capabilities in this domain are new in v3.1.0.

Domain Characteristics:

  • Primary function: Specimen type configuration management (CRUD operations)
  • Secondary function: Target name suffix-to-specimen mapping (CRUD and derivation)
  • Tertiary function: Automatic specimen assignment during import via suffix matching
  • Configuration dependency: use_sample_type client configuration, help_items feature flag, site scoping

Test Method Rationale: Per Test Plan section 3.3, configuration domains use TM-API as primary method with TM-UI fallback. Specimen management endpoints have deterministic validation logic (uniqueness, site scoping, case-insensitive suffix matching). API-level testing provides faster, more reliable coverage. UI testing supplements for access-control visibility (sidebar links, Config Mode gating).

Test Case Convention: Steps describe logical actions, not UI mechanics. Use "Create specimen type" or "Submit suffix mapping", not "Click the Add button" or "Select from dropdown". This ensures test intent survives UI redesigns.


Coverage Summary

REQ IDTitleACsTestsAC CoverageMethodGaps
REQ-SPECIMEN-001Specimen Types Page Access4TC-SPECIMEN-0014/4 (100%)TM-API, TM-UINone
REQ-SPECIMEN-002Specimen Types Table5TC-SPECIMEN-0025/5 (100%)TM-APINone
REQ-SPECIMEN-003Add Specimen6TC-SPECIMEN-0036/6 (100%)TM-APINone
REQ-SPECIMEN-004Edit Specimen5TC-SPECIMEN-0045/5 (100%)TM-API, TM-UINone
REQ-SPECIMEN-005Delete Specimen with Warning3TC-SPECIMEN-0053/3 (100%)TM-APINone
REQ-SPECIMEN-006Target Suffix Page Access4TC-SPECIMEN-0064/4 (100%)TM-UINone
REQ-SPECIMEN-007Target Suffix Mapping Table5TC-SPECIMEN-0075/5 (100%)TM-APINone
REQ-SPECIMEN-008Add Target Suffix Mapping6TC-SPECIMEN-0086/6 (100%)TM-APINone
REQ-SPECIMEN-009Edit Target Suffix Mapping6TC-SPECIMEN-0096/6 (100%)TM-APINone
REQ-SPECIMEN-010Delete Target Suffix Mapping4TC-SPECIMEN-0104/4 (100%)TM-APINone
REQ-SPECIMEN-011Suffix Matching During Import4TC-SPECIMEN-0114/4 (100%)TM-APINone
REQ-SPECIMEN-012Help Data Toggle3TC-SPECIMEN-0123/3 (100%)TM-UINone

Totals: 12 REQs, 55 ACs, 12 Test Cases, 100% Coverage


Test Cases

TC-SPECIMEN-001: Specimen Types page access control

Verifies: REQ-SPECIMEN-001 (AC1-4: Access Control, Route, Error Handling)

Method: TM-API, TM-UI

Priority: High

Version: @V3_1_0

Preconditions:

  • Two users configured: one SUPER_ADMIN, one non-SUPER_ADMIN (e.g., MANAGER)
  • Config Mode available

Test Vectors:

TVInputExpectedAC
TV-001SUPER_ADMIN navigates to Config Mode sidebar "Other Settings""Specimen types" link is visibleAC1
TV-002SUPER_ADMIN accesses /specimens?config_mode=truePage loads successfully with 200 statusAC3
TV-003Non-SUPER_ADMIN (MANAGER) navigates to Config Mode sidebar "Other Settings""Specimen types" link is not visibleAC2
TV-004Non-SUPER_ADMIN attempts direct navigation to /specimens?config_mode=trueAccess deniedAC4

Expected Results:

  • AC1: "Specimen types" link appears in "Other Settings" submenu for SUPER_ADMIN users
  • AC2: "Specimen types" link does not appear for non-SUPER_ADMIN users
  • AC3: Page served at route /specimens?config_mode=true
  • AC4: Non-SUPER_ADMIN direct navigation returns access denied

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-002: Specimen types table display and site scoping

Verifies: REQ-SPECIMEN-002 (AC1-5: Display, Columns, Site Scoping)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site A has specimens: "Plasma" (use_quant=true), "Serum" (use_quant=false)
  • Site B has specimen: "CSF" (use_quant=true)

Test Data:

Specimen NameUse QuantificationSite
PlasmatrueSite A
SerumfalseSite A
CSFtrueSite B

Test Vectors:

TVInputExpectedAC
TV-001GET /api/specimens as Site A userReturns "Plasma" and "Serum" onlyAC1, AC5
TV-002Verify response structureEach specimen has specimen_name and use_quant fieldsAC2
TV-003GET /api/specimens for a site with no specimensReturns empty arrayAC3
TV-004Site A user attempts to access Site B specimen by ID404 responseAC5
TV-005GET /api/specimens as Site B userReturns "CSF" only, not "Plasma" or "Serum"AC4

Expected Results:

  • AC1: All specimens for the user's logged-in site are returned
  • AC2: Response includes specimen_name and use_quant fields
  • AC3: Empty array returned when no specimens exist for site
  • AC4: Specimens from other sites are not returned
  • AC5: API queries scoped by user's logged_in_site_id; cross-site access returns 404

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-003: Create new specimen type

Verifies: REQ-SPECIMEN-003 (AC1-6: Add Panel, Validation, Batch Save)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site has no existing specimen named "Nasopharyngeal Swab"
  • Site has existing specimen named "Plasma"

Test Data:

FieldValid ValueInvalid Value
specimen_name"Nasopharyngeal Swab""" (empty), "Plasma" (duplicate)
use_quantfalse (default), trueN/A

Test Vectors:

TVInputExpectedAC
TV-001POST /api/specimens with specimen_name: "Nasopharyngeal Swab", use_quant: false201 Created; specimen returned with generated UUIDAC1, AC2
TV-002POST /api/specimens with specimen_name: "Nasopharyngeal Swab", use_quant: true201 Created; specimen has use_quant=trueAC2
TV-003POST /api/specimens with specimen_name: "Plasma" (already exists)422 error: Specimen "Plasma" already exists.AC4, AC5
TV-004POST /api/specimens with specimen_name: "" (empty)422 validation errorAC6
TV-005POST /api/specimens with specimen_name exceeding 255 characters422 validation errorAC4
TV-006After successful create, GET /api/specimensNew specimen appears in listingAC3

Expected Results:

  • AC1: New specimen created with provided name and use_quant value
  • AC2: Default use_quant is false when not provided; true when explicitly set
  • AC3: After save, specimen appears in the table listing
  • AC4: Duplicate name returns 422 with descriptive error message
  • AC5: Specimen name must be unique per site (case-insensitive)
  • AC6: Empty specimen name rejected by validation

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-004: Edit existing specimen type

Verifies: REQ-SPECIMEN-004 (AC1-5: Edit Panel, Working Set, Unsaved Changes)

Method: TM-API, TM-UI

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site has specimen "Plasma" with use_quant=false

Test Vectors:

TVInputExpectedAC
TV-001PUT /api/specimens/{id} with use_quant: true200 OK; specimen returned with use_quant=trueAC1, AC3
TV-002PUT /api/specimens/{id} without changing use_quant200 OK; specimen unchangedAC2
TV-003Verify specimen_name is not modifiable via PUTspecimen_name remains "Plasma" regardless of request bodyAC1
TV-004PUT /api/specimens/{id} for specimen belonging to different site404 responseAC3
TV-005(UI) Open edit panel, modify use_quant, attempt to close panelUnsaved changes warning dialog with Save/Discard/CancelAC4, AC5

Expected Results:

  • AC1: Specimen name is read-only (immutable after creation); only use_quant is editable
  • AC2: Confirm Changes button disabled when form is unmodified
  • AC3: Confirmed edits tracked in working set for batch save
  • AC4: Footer navigation (Next/Previous) allows navigating between pending changes
  • AC5: Unsaved changes trigger warning dialog on panel close

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-005: Delete specimen type with association warning

Verifies: REQ-SPECIMEN-005 (AC1-3: Deletion, Association Warning)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site has specimen "Orphan" with no associations (no suffix mappings, test codes, reportings, or combined outcomes)
  • Site has specimen "Serum" with an existing suffix mapping association

Test Vectors:

TVInputExpectedAC
TV-001Delete specimen "Orphan" (no associations)Specimen deleted successfullyAC1
TV-002Attempt to delete specimen "Serum" (has associations)Warning displayed indicating downstream impact before confirmationAC2
TV-003Confirm deletion of specimen "Serum" after warningSpecimen removed from site configurationAC3

Expected Results:

  • AC1: Deletion available for specimens without blocking constraints
  • AC2: When specimen has associations, warning indicates scope of downstream impact
  • AC3: After confirmed deletion, specimen removed from site configuration

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-006: Target Name Suffix page access control

Verifies: REQ-SPECIMEN-006 (AC1-4: Access Control, Configuration Gating)

Method: TM-UI

Priority: High

Version: @V3_1_0

Preconditions:

  • Two users: SUPER_ADMIN, non-SUPER_ADMIN
  • use_sample_type client configuration is configurable per test vector

Test Vectors:

TVInputExpectedAC
TV-001SUPER_ADMIN with use_sample_type = "From Target Suffix", open Config Mode sidebar "Other Settings""Target Name Suffix to Specimen" link visibleAC1, AC2
TV-002SUPER_ADMIN with use_sample_type != "From Target Suffix", open Config Mode sidebar"Target Name Suffix to Specimen" link not visibleAC2
TV-003Non-SUPER_ADMIN with use_sample_type = "From Target Suffix", open Config Mode sidebar"Target Name Suffix to Specimen" link not visibleAC3
TV-004SUPER_ADMIN accesses /target-name-suffix-to-specimen?config_mode=true with correct configPage loads successfullyAC4

Expected Results:

  • AC1: Link appears in "Other Settings" submenu for SUPER_ADMIN users
  • AC2: Link only visible when use_sample_type equals "From Target Suffix"
  • AC3: Non-SUPER_ADMIN users cannot see the link regardless of configuration
  • AC4: Page served at route /target-name-suffix-to-specimen?config_mode=true

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-007: Target suffix mapping table display

Verifies: REQ-SPECIMEN-007 (AC1-5: Display, Site Scoping)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site A has suffix mappings: "NPS" -> "Nasopharyngeal Swab", "PL" -> "Plasma"
  • Site B has suffix mapping: "SER" -> "Serum"
  • use_sample_type = "From Target Suffix"

Test Data:

Target Name SuffixSpecimen NameSite
NPSNasopharyngeal SwabSite A
PLPlasmaSite A
SERSerumSite B

Test Vectors:

TVInputExpectedAC
TV-001GET /api/target-name-suffix-to-specimen as Site A userReturns mappings "NPS" and "PL" with specimen namesAC1
TV-002Verify response structureEach mapping has target_name_suffix (uppercase) and specimen_nameAC2
TV-003GET /api/target-name-suffix-to-specimen for site with no mappingsReturns empty resultAC3
TV-004GET /api/target-name-suffix-to-specimen as Site B userReturns "SER" only, not "NPS" or "PL"AC4
TV-005Verify suffix uniqueness constraint(target_name_suffix, site_id) is unique at database levelAC5

Expected Results:

  • AC1: All suffix-to-specimen mappings for user's site returned
  • AC2: Suffixes displayed in uppercase; specimen names shown (or "-" if empty)
  • AC3: Empty result when no mappings exist for site
  • AC4: Data scoped to user's site; other sites' mappings not returned
  • AC5: Unique constraint on (target_name_suffix, site_id) at database level

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-008: Create target name suffix mapping

Verifies: REQ-SPECIMEN-008 (AC1-6: Add Panel, Suffix Validation, Inline Specimen Creation)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site has specimen "Plasma"
  • Site has existing suffix mapping "NPS" -> "Nasopharyngeal Swab"
  • use_sample_type = "From Target Suffix"

Test Data:

FieldValid ValueInvalid Value
target_name_suffix"PL""NPS" (duplicate), "" (empty)
specimen_idUUID of "Plasma"null

Test Vectors:

TVInputExpectedAC
TV-001POST suffix mapping with suffix "pl" and specimen "Plasma"Mapping created with suffix stored as "PL" (uppercase)AC1, AC3
TV-002POST suffix mapping with suffix "nps" (case-insensitive duplicate of existing "NPS")Validation error: "Suffix should be unique (case-insensitive)"AC4, AC5
TV-003POST suffix mapping with empty suffixValidation error: required fieldAC6
TV-004Create a new specimen "CSF" via inline creation, then use it in a new mappingSpecimen created; mapping created with "CSF" as specimenAC2
TV-005After successful mapping creation, GET /api/target-name-suffix-to-specimenNew mapping appears in listingAC1
TV-006POST suffix mapping with valid dataSuccess message returned; table refreshesAC1

Expected Results:

  • AC1: Mapping created with suffix and specimen association
  • AC2: Inline specimen creation supported without leaving the page
  • AC3: All suffixes normalized to UPPERCASE before storage
  • AC4: Duplicate suffix (case-insensitive) rejected with validation error
  • AC5: Error message: "Suffix should be unique (case-insensitive)"
  • AC6: Missing required fields prevented by validation

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-009: Edit target suffix mapping

Verifies: REQ-SPECIMEN-009 (AC1-6: Edit Panel, Batch Save, Unsaved Changes)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site has suffix mappings: "NPS" -> "Nasopharyngeal Swab", "PL" -> "Plasma"
  • Site has specimen "Serum" available for reassignment
  • use_sample_type = "From Target Suffix"

Test Vectors:

TVInputExpectedAC
TV-001PUT /api/target-name-suffix-to-specimen changing "NPS" mapping from "Nasopharyngeal Swab" to "Serum"200 OK; "NPS" now maps to "Serum"AC1, AC4
TV-002Verify suffix value is immutable during editTarget name suffix "NPS" remains unchanged in responseAC2
TV-003PUT with specimen_id set to nullValidation error: specimen is requiredAC3
TV-004PUT with batch of modified mappingsAll modified mappings updated in single API callAC4
TV-005PUT attempting to create suffix collision (case-insensitive)Backend validation rejects duplicate suffixAC4
TV-006(UI) Open edit panel, modify specimen, attempt to closeUnsaved changes warning with Save/Discard/CancelAC5, AC6

Expected Results:

  • AC1: Suffix value displayed as disabled (read-only) field
  • AC2: Specimen editable via dropdown selector (required)
  • AC3: Confirm Changes button disabled if form is invalid or unmodified
  • AC4: Batch save sends all modified mappings in single PUT call; backend validates for duplicate suffixes (case-insensitive)
  • AC5: On success: success message displayed, table refreshes
  • AC6: Closing edit panel with unsaved modifications triggers warning dialog

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-010: Delete target suffix mapping

Verifies: REQ-SPECIMEN-010 (AC1-4: Confirmation, Deletion, Cancellation)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • Site A has suffix mapping "NPS" -> "Nasopharyngeal Swab"
  • Site B has a different suffix mapping
  • use_sample_type = "From Target Suffix"

Test Vectors:

TVInputExpectedAC
TV-001DELETE /api/target-name-suffix-to-specimen/{id} for own site mappingHTTP 204 No Content; mapping removedAC2
TV-002After deletion, GET /api/target-name-suffix-to-specimenDeleted mapping no longer in listingAC2
TV-003DELETE /api/target-name-suffix-to-specimen/{id} for mapping belonging to different site404 responseAC2
TV-004(UI) Click delete, cancel confirmation dialogMapping remains unchangedAC4

Expected Results:

  • AC1: Confirmation dialog displayed with suffix name before deletion
  • AC2: Confirmed deletion sends DELETE request; backend verifies site ownership (404 on mismatch); HTTP 204 on success
  • AC3: After deletion, table refreshes and selection clears if deleted mapping was selected
  • AC4: Cancelling the dialog leaves the mapping unchanged

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-011: Automatic specimen assignment via suffix matching during import

Verifies: REQ-SPECIMEN-011 (AC1-4: Matching Logic, Downstream Effects)

Method: TM-API

Priority: High

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • use_sample_type = "From Target Suffix"
  • Site has suffix mappings: "NPS" -> "Nasopharyngeal Swab", "PL" -> "Plasma"
  • Mix configured with targets that will match imported target names
  • Reporting cut-offs or combined outcomes configured for specimen-specific behavior

Test Data:

Target Name in RunfileConfigured SuffixExpected Specimen
HIV-NPSNPSNasopharyngeal Swab
COVID-PLPLPlasma
HIV-IC(none match)No specimen assigned

Test Vectors:

TVInputExpectedAC
TV-001Import runfile containing target "HIV-NPS" with suffix mapping "NPS" -> "Nasopharyngeal Swab"Observations for "HIV-NPS" associated with specimen type "Nasopharyngeal Swab"AC1, AC2
TV-002Import runfile containing target "HIV-IC" with no matching suffixNo specimen type assigned to "HIV-IC" observationsAC3
TV-003Import runfile with target "COVID-PL"; suffix matching is case-insensitive against uppercase-stored suffixObservations for "COVID-PL" associated with specimen type "Plasma"AC2
TV-004Configure specimen-specific reporting cut-off for "Nasopharyngeal Swab"; import runfile with matching targetSpecimen-specific reporting configuration applied instead of "Any" defaultAC4

Expected Results:

  • AC1: System compares each target name against all configured suffixes for the site during import
  • AC2: Matching performed against uppercase-normalized suffix; matched targets assigned associated specimen type
  • AC3: When no suffix matches, no specimen type is assigned (existing behavior preserved)
  • AC4: Specimen-specific configuration takes precedence over non-specimen ("Any") configuration when both exist

Automation Status: Planned

Jira: BT-5894


TC-SPECIMEN-012: Help data toggle on Target Suffix page

Verifies: REQ-SPECIMEN-012 (AC1-3: Feature-Flag Gating, Toggle Behavior)

Method: TM-UI

Priority: Low

Version: @V3_1_0

Preconditions:

  • User logged in as SUPER_ADMIN
  • use_sample_type = "From Target Suffix"
  • help_items feature flag is configurable per test vector

Test Vectors:

TVInputExpectedAC
TV-001Navigate to Target Suffix page with help_items feature flag enabledHelp data toggle is visible on the pageAC1
TV-002Activate the help data toggleContextual help information displayedAC2
TV-003Deactivate the help data toggleHelp content hiddenAC3

Expected Results:

  • AC1: Help data toggle visible only when help_items feature flag is enabled
  • AC2: Activating toggle displays contextual help information
  • AC3: Deactivating toggle hides help content

Automation Status: Planned

Jira: BT-5894


Traceability

REQ-to-TC Cross Reference

REQ IDTest CasesCoverage
REQ-SPECIMEN-001TC-SPECIMEN-0014/4 AC
REQ-SPECIMEN-002TC-SPECIMEN-0025/5 AC
REQ-SPECIMEN-003TC-SPECIMEN-0036/6 AC
REQ-SPECIMEN-004TC-SPECIMEN-0045/5 AC
REQ-SPECIMEN-005TC-SPECIMEN-0053/3 AC
REQ-SPECIMEN-006TC-SPECIMEN-0064/4 AC
REQ-SPECIMEN-007TC-SPECIMEN-0075/5 AC
REQ-SPECIMEN-008TC-SPECIMEN-0086/6 AC
REQ-SPECIMEN-009TC-SPECIMEN-0096/6 AC
REQ-SPECIMEN-010TC-SPECIMEN-0104/4 AC
REQ-SPECIMEN-011TC-SPECIMEN-0114/4 AC
REQ-SPECIMEN-012TC-SPECIMEN-0123/3 AC

API Endpoint Coverage

EndpointMethodTest Cases
/api/specimensGETTC-SPECIMEN-002, TC-SPECIMEN-003
/api/specimensPOSTTC-SPECIMEN-003
/api/specimens/{specimen}PUTTC-SPECIMEN-004
/api/target-name-suffix-to-specimenGETTC-SPECIMEN-007, TC-SPECIMEN-008
/api/target-name-suffix-to-specimenPOSTTC-SPECIMEN-008
/api/target-name-suffix-to-specimenPUTTC-SPECIMEN-009
/api/target-name-suffix-to-specimen/{id}DELETETC-SPECIMEN-010

Dependencies

Test CaseDepends On
TC-SPECIMEN-006use_sample_type client configuration set to "From Target Suffix"
TC-SPECIMEN-007 through TC-SPECIMEN-010TC-SPECIMEN-006 (page access requires configuration)
TC-SPECIMEN-011Configured suffix mappings (TC-SPECIMEN-008), import pipeline availability
TC-SPECIMEN-012help_items feature flag enabled

Notes

  • All specimen management capabilities are new in v3.1.0. Every test case carries the @V3_1_0 version tag.
  • The specimen API routes (GET/POST/PUT) do not have explicit user-type middleware in the route definition; access control for the CRUD UI is enforced at the Config Mode sidebar level (SUPER_ADMIN only). API-level tests should verify behavior with authenticated users of appropriate role.
  • The suffix matching logic (TC-SPECIMEN-011) integrates with the runfile import pipeline. Testing requires a complete import flow -- suffix mappings must be configured before importing a runfile that exercises the matching.
  • REQ-SPECIMEN-005 (delete) -- the SRS mentions association warnings but the controller code (SpecimensController.php) does not currently expose a delete endpoint. The delete behavior may be handled client-side or via a separate endpoint not yet present in v3.0.1 code. Tests should be validated against v3.1.0 code.
  • Specimens created via inline creation on the Target Suffix page (TC-SPECIMEN-008 TV-004) use the same POST /api/specimens endpoint as the dedicated Specimen Types page, so validation rules are identical.