-module(infra_secrets_tests). -include_lib("eunit/include/eunit.hrl"). -define(STRONG_JWT, <<"this-is-a-strong-user-jwt-secret-32b">>). -define(STRONG_ADMIN, <<"this-is-a-strong-admin-jwt-secret32">>). setup() -> application:load(eventhub), ok. cleanup(_) -> application:unset_env(eventhub, jwt_secret), application:unset_env(eventhub, admin_jwt_secret), os:unsetenv("EVENTHUB_ENV"), os:unsetenv("JWT_SECRET"), os:unsetenv("ADMIN_JWT_SECRET"), ok. with_env(Key, Val, Fun) -> os:putenv(Key, Val), try Fun() after os:unsetenv(Key) end. infra_secrets_test_() -> {foreach, fun setup/0, fun cleanup/1, [ {"dev mode allows missing secrets", fun test_dev_missing_ok/0}, {"stage rejects missing JWT_SECRET", fun test_stage_missing_jwt/0}, {"stage rejects weak JWT_SECRET", fun test_stage_weak_jwt/0}, {"stage accepts strong secrets", fun test_stage_strong_ok/0}, {"require_admin_seed_password rejects 123456", fun test_weak_admin_password/0} ]}. test_dev_missing_ok() -> with_env("EVENTHUB_ENV", "dev", fun() -> ?assertEqual(dev, infra_secrets:mode()), ?assertEqual(ok, infra_secrets:validate_startup()) end). test_stage_missing_jwt() -> with_env("EVENTHUB_ENV", "stage", fun() -> ?assertMatch({error, {missing_secret, jwt_secret}}, infra_secrets:validate_startup()) end). test_stage_weak_jwt() -> with_env("EVENTHUB_ENV", "stage", fun() -> os:putenv("JWT_SECRET", "123456"), os:putenv("ADMIN_JWT_SECRET", binary_to_list(?STRONG_ADMIN)), ?assertMatch({error, {weak_secret, jwt_secret}}, infra_secrets:validate_startup()) end). test_stage_strong_ok() -> with_env("EVENTHUB_ENV", "stage", fun() -> os:putenv("JWT_SECRET", binary_to_list(?STRONG_JWT)), os:putenv("ADMIN_JWT_SECRET", binary_to_list(?STRONG_ADMIN)), ?assertEqual(ok, infra_secrets:validate_startup()) end). test_weak_admin_password() -> os:putenv("ADMIN_PASSWORD", "123456"), ?assertMatch({error, {weak_secret, 'ADMIN_PASSWORD'}}, infra_secrets:require_admin_seed_password("ADMIN_PASSWORD")).