| ID | Level | Scenario | Expected result |
|---|---|---|---|
| T01 | Unit | CSV with BOM, quoted commas, blank rows, duplicate case variants, malformed addresses | Preview explains each rejection; committed contacts are unique and source is retained. |
| T02 | Unit | Import a previously suppressed address | Suppression remains active and campaign preflight excludes it. |
| T03 | Unit | Empty subject, missing sender/postal address/opt-out route, unknown merge field | Approval blocked with actionable errors. |
| T04 | Unit | Imported HTML template or contact field includes script, event handler, active object, javascript: URL, or HTML metacharacters |
Active content is blocked; merged values are escaped; preview cannot execute script in the HTA. |
| T05 | Unit | Three queued recipients across two campaigns with five-minute minimum interval | Attempt timestamps are at least five minutes apart across both campaigns, including after a failure or retry. |
| T06 | Unit | Due send occurs overnight, on a weekend, or across a daylight-saving change while the HTA remains open | Dispatch remains eligible at any hour; UTC pacing gap holds; displayed local time is correct. |
| T07 | Integration | Attempt to launch two HTA instances | Only one instance may dispatch; one provider request is made. |
| T08 | Integration | HTA closes or crashes before, during, and after provider call | No new send begins after close; durable state survives; uncertain outcomes are flagged and not retried automatically. |
| T09 | Integration | SMTP timeout, transient 4xx, permanent 5xx, TLS failure, or authentication rejection | Transient cases back off; permanent cases stop; connection or credential issue pauses and surfaces an action. |
| T10 | Integration | Pause/cancel while a send is in flight | Current outcome is saved; no next attempt starts. |
| T11 | Integration | Sleep/offline period covering several slots | No catch-up burst on wake; next send follows the persisted pacing clock. |
| T12 | Integration | Opt-out arrives between queue selection and dispatch | Last-moment suppression check skips recipient. |
| T13 | Integration | Test-send action | Only configured internal test address receives a message; live delivery counts do not advance. |
| T14 | End to end | 10 internal test addresses across restart | Each recipient is attempted at most once in ordinary paths; report matches provider requests. |
| T15 | Operations | Backup and restore queue, campaigns, and suppressions | Restored system resumes without lost opt-outs or accidental duplicate sends. |
| T16 | Security | Inspect files/logs and run as least-privileged account | No secrets in app files or logs; unauthorized local account cannot read contact store. |
| T17 | Unit | Load example INI; change QUEUE_INTERVAL from 300 to another allowed value; try missing/invalid port, TLS flags, send mode, image limits, or postal address |
Valid values take effect according to their documented lifecycle; invalid transport values block sending; missing postal address blocks new campaign approval with a clear error. |
| T18 | Integration | Fake SMTP server refuses STARTTLS or presents an invalid certificate | Sender fails closed; it does not send credentials or message content in plaintext. |
| T19 | Integration | Launch with x86 and x64 hosts, a missing provider, a missing MDB, and an unsupported schema version | Only a matching host/provider with an openable configured MDB and supported schema starts the HTA; other cases show actionable errors before UI launch. |
| T20 | Operations | Send an unsubscribe reply to the monitored mailbox and process it during daily review | Owner records suppression; no later queued send goes to that address. |
| T21 | Integration | Import two HTML templates, approve a campaign with one, then edit its source .html and image files |
The campaign sends its approved HTML and image snapshots; source edits do not change queued content. |
| T22 | Integration | Send an internal test message with a local PNG/JPEG image | Raw MIME contains multipart/related, matching cid: references and inline image parts; no local paths appear in the received message. |
| T23 | Unit | Import a template with path traversal, an absolute path, unsupported image type, or oversized image | Import blocks the asset with a clear reason and never reads outside the selected template folder. |
| T24 | Manual integration | Open the internal test message in the intended desktop and web mail clients | HTML and inline images render as expected; reply address, postal address, and opt-out wording are visible. |
| T25 | Integration | Change sender/reply/postal INI values and source template after approving a campaign | Existing campaign keeps its approved identity, footer, HTML, and images; a new campaign can use the new values. |
| T26 | Unit | Shorten or lengthen QUEUE_INTERVAL while a prior attempt's gap is still pending |
The next send occurs no earlier than both the old reserved time and the new interval measured from the last attempt. |
| T27 | Operations | Restore the database under another Windows identity | Campaign and suppression data restore; SMTP password cannot be decrypted and must be entered again before sending. |
| T28 | Integration | Close the HTA with a due campaign, wait past several intervals, then reopen | No sends occur while closed; reopening requires explicit resume and causes no catch-up burst. |
| T29 | Integration | Invoke provider probe from both 32-bit and 64-bit script hosts on target PC | Diagnostic reports actual MDB create/write/read capability per provider and architecture; startup uses the verified architecture. |
| T30 | Integration | Save and rotate synthetic SMTP passwords in a disposable MDB, then reopen under the same Windows user | DPAPI value round trips and rotates; plaintext does not appear in INI or command arguments. |
| T31 | Integration | Build internal test message to a local pickup folder | Exactly one HTML message is produced with multipart/related and a CID-linked inline image; no network send occurs. |
| T32 | Manual integration | After local password setup, press the HTA's internal test button | Exactly one message goes to configured SMTP_TEST_TO; owner confirms authentication and image rendering in the inbox. |
Powered by TurnKey Linux.