feat(sp40): edifabric.api_key secret wiring + dev fixture
This commit is contained in:
@@ -155,4 +155,10 @@ def has_keyring() -> bool:
|
|||||||
# ``CYCLONE_SFTP_PASSWORD`` (env var).
|
# ``CYCLONE_SFTP_PASSWORD`` (env var).
|
||||||
_ENV_NAME_FOR: dict[str, str] = {
|
_ENV_NAME_FOR: dict[str, str] = {
|
||||||
"sftp.gainwell.password": "CYCLONE_SFTP_PASSWORD",
|
"sftp.gainwell.password": "CYCLONE_SFTP_PASSWORD",
|
||||||
|
# SP40: Edifabric /v2/x12/validate API key. Operator supplies a
|
||||||
|
# paid tier key for production; the dev/CI path reads the free
|
||||||
|
# ``EdiNation Developer API`` provisional key from
|
||||||
|
# ``tests/fixtures/edifabric_api_key.txt`` (gitignored copy in
|
||||||
|
# production deployments — see Task 6 plan).
|
||||||
|
"edifabric.api_key": "CYCLONE_EDIFABRIC_API_KEY",
|
||||||
}
|
}
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
# SP40: dev-only public eval key for the EdiNation / Edifabric
|
||||||
|
# /v2/x12/validate reference parser. This key has hit the public
|
||||||
|
# evaluation docs and is documented as a "developer API" provisional
|
||||||
|
# key — fine for local CI / smoke tests, never ship to production.
|
||||||
|
#
|
||||||
|
# Production deployments MUST override via the secrets layer:
|
||||||
|
#
|
||||||
|
# cyclone secrets set edifabric.api_key <paid-tier-key>
|
||||||
|
# # or
|
||||||
|
# export CYCLONE_EDIFABRIC_API_KEY_FILE=/path/to/paid-key.txt
|
||||||
|
#
|
||||||
|
# The fixture is referenced by name so the URL-reminder route survives
|
||||||
|
# refactors; the actual key isn't sent over the wire because every
|
||||||
|
# test patches edifabric.set_transport_factory() and secrets.get_secret
|
||||||
|
# before invoke.
|
||||||
|
3ecf6b1c5cf34bd797a5f4c57951a1cf
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
"""SP40: tests for the edifabric.api_key secret wiring.
|
||||||
|
|
||||||
|
Specifically: the ``_ENV_NAME_FOR`` table maps ``edifabric.api_key``
|
||||||
|
to ``CYCLONE_EDIFABRIC_API_KEY`` so operators can configure via env
|
||||||
|
var (or via file companion per ``secrets.get_secret``'s
|
||||||
|
``<env_name>_FILE`` form) without touching the macOS Keychain.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def test_env_name_for_maps_edifabric_api_key():
|
||||||
|
from cyclone.secrets import _ENV_NAME_FOR
|
||||||
|
assert _ENV_NAME_FOR["edifabric.api_key"] == "CYCLONE_EDIFABRIC_API_KEY"
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_secret_reads_edifabric_key_from_env(monkeypatch):
|
||||||
|
"""With the env var set, ``get_secret('edifabric.api_key')``
|
||||||
|
returns it without touching the Keychain."""
|
||||||
|
monkeypatch.setenv("CYCLONE_EDIFABRIC_API_KEY", "test-env-key-9876")
|
||||||
|
|
||||||
|
from cyclone import secrets
|
||||||
|
assert secrets.get_secret("edifabric.api_key") == "test-env-key-9876"
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_secret_reads_edifabric_key_from_file(monkeypatch, tmp_path):
|
||||||
|
"""With ``<env_name>_FILE`` set, ``get_secret`` reads the key from
|
||||||
|
the file (no Keychain touch). Mirrors the existing SFTP password
|
||||||
|
file-companion pattern (SP25)."""
|
||||||
|
key_file = tmp_path / "edi_key"
|
||||||
|
key_file.write_text("file-companion-key-5555\n")
|
||||||
|
monkeypatch.setenv("CYCLONE_EDIFABRIC_API_KEY_FILE", str(key_file))
|
||||||
|
|
||||||
|
from cyclone import secrets
|
||||||
|
assert secrets.get_secret("edifabric.api_key") == "file-companion-key-5555"
|
||||||
|
|
||||||
|
|
||||||
|
def test_dev_fixture_file_exists_and_contains_eval_key():
|
||||||
|
"""The dev-only fixture exists at the documented path so the
|
||||||
|
eval key is referenceable; the CI mocks intercept before any
|
||||||
|
real HTTP happens."""
|
||||||
|
fixture = Path("tests/fixtures/edifabric_api_key.txt")
|
||||||
|
assert fixture.exists(), (
|
||||||
|
f"dev-only Edifabric API key fixture is missing at {fixture}"
|
||||||
|
)
|
||||||
|
contents = fixture.read_text().strip()
|
||||||
|
# Public eval key from the EdiNation API docs.
|
||||||
|
assert "3ecf6b1c5cf34bd797a5f4c57951a1cf" in contents
|
||||||
Reference in New Issue
Block a user