Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion nitrostack/auth/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ def __init__(
# Merge system environment variables first
self._config.update(os.environ)

# Parse .env manually (no stdout prints allowed)
# Parse .env manually (no stdout prints allowed). The process
# environment wins, as with python-dotenv and Node's dotenv: a host
# that starts the server with PORT=3001 must not be overridden by the
# PORT=3000 that `nitrostack init` writes into .env.
if not ignore_env_file and os.path.exists(env_file_path):
try:
with open(env_file_path, "r", encoding="utf-8") as f:
Expand All @@ -31,6 +34,8 @@ def __init__(
k, v = line.split("=", 1)
k = k.strip()
v = v.strip().strip("'\"") # Remove wrapping quotes
if k in os.environ:
continue
self._config[k] = v
os.environ[k] = v
except Exception as e:
Expand Down
30 changes: 30 additions & 0 deletions tests/test_auth_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,33 @@ def test_api_key_empty_string_is_rejected(monkeypatch):
service = DIContainer.get_instance().resolve(ApiKeyService)
assert service.validate("") is False
assert service.validate("anything") is False


def test_config_process_env_wins_over_env_file(tmp_path, monkeypatch):
from nitrostack.core.app import resolve_http_port

env_file = tmp_path / ".env"
env_file.write_text("PORT=3000\nFROM_FILE=file\n", encoding="utf-8")
monkeypatch.setenv("PORT", "3001")
monkeypatch.delenv("FROM_FILE", raising=False)
ConfigModule.for_root(env_file_path=str(env_file), defaults={"PORT": "9999", "ONLY_DEFAULT": "d"})
cfg = DIContainer.get_instance().resolve(ConfigService)
assert cfg.get("PORT") == "3001"
assert resolve_http_port() == 3001
# Keys the process doesn't set still come from the file, then defaults.
assert cfg.get("FROM_FILE") == "file"
assert cfg.get("ONLY_DEFAULT") == "d"
monkeypatch.delenv("FROM_FILE", raising=False)


def test_config_env_file_port_applies_when_process_has_none(tmp_path, monkeypatch):
from nitrostack.core.app import resolve_http_port

env_file = tmp_path / ".env"
env_file.write_text("PORT=3005\n", encoding="utf-8")
monkeypatch.delenv("PORT", raising=False)
ConfigModule.for_root(env_file_path=str(env_file), defaults={"PORT": "3000"})
cfg = DIContainer.get_instance().resolve(ConfigService)
assert cfg.get("PORT") == "3005"
assert resolve_http_port() == 3005
monkeypatch.delenv("PORT", raising=False)
Loading