Spaces:
Sleeping
Sleeping
| import importlib.util | |
| import json | |
| import os | |
| from pathlib import Path | |
| import sys | |
| import pytest | |
| SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "final_env_wizard.py" | |
| SPEC = importlib.util.spec_from_file_location("final_env_wizard", SCRIPT_PATH) | |
| final_env_wizard = importlib.util.module_from_spec(SPEC) | |
| assert SPEC.loader is not None | |
| sys.modules[SPEC.name] = final_env_wizard | |
| SPEC.loader.exec_module(final_env_wizard) | |
| def test_final_env_wizard_check_requires_ignored_output(tmp_path): | |
| (tmp_path / ".gitignore").write_text(".env.*\n!.env.final.example\n", encoding="utf-8") | |
| report = final_env_wizard.build_check(tmp_path, tmp_path / ".env.final.local") | |
| assert report["ok"] is True | |
| assert report["git_ignored"] is True | |
| assert report["env_file_present"] is False | |
| assert report["ready_for_live_entry"] is False | |
| assert "B2_APPLICATION_KEY" in report["secret_fields"] | |
| assert "B2_APP_KEY" in report["secret_fields"] | |
| assert "GMI_API_KEY" in report["secret_fields"] | |
| assert "OPENAI_API_KEY" in report["secret_fields"] | |
| def test_final_env_wizard_check_fails_for_unignored_output(tmp_path): | |
| (tmp_path / ".gitignore").write_text("var/\n", encoding="utf-8") | |
| report = final_env_wizard.build_check(tmp_path, tmp_path / "final.env") | |
| assert report["ok"] is False | |
| assert report["git_ignored"] is False | |
| def test_final_env_wizard_check_reports_existing_env_readiness_without_values(tmp_path): | |
| (tmp_path / ".gitignore").write_text(".env.*\n!.env.final.example\n", encoding="utf-8") | |
| env_path = tmp_path / ".env.final.local" | |
| env_path.write_text( | |
| "\n".join( | |
| [ | |
| "PROOFFRAME_STORAGE_BACKEND=b2", | |
| "PROOFFRAME_GENERATION_BACKEND=genblaze", | |
| "B2_ENDPOINT_URL=https://s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET=proofframe-demo-a6b4e49", | |
| "B2_KEY_ID=least-privilege-key-id", | |
| "B2_APP_KEY=secret-b2-key", | |
| "GENBLAZE_API_KEY=secret-gmi-key", | |
| "GENBLAZE_IMAGE_MODEL=seedream-5.0-lite", | |
| ] | |
| ) | |
| + "\n", | |
| encoding="utf-8", | |
| ) | |
| os.chmod(env_path, 0o600) | |
| report = final_env_wizard.build_check(tmp_path, env_path) | |
| serialized = json.dumps(report) | |
| assert report["ok"] is True | |
| assert report["env_file_present"] is True | |
| assert report["env_file_mode_ok"] is True | |
| assert report["missing_required_names"] == [] | |
| assert report["placeholder_names"] == [] | |
| assert report["b2_region"]["derived_from_endpoint"] == "us-west-004" | |
| assert report["ready_for_live_entry"] is True | |
| assert "secret-b2-key" not in serialized | |
| assert "secret-gmi-key" not in serialized | |
| def test_final_env_wizard_check_reports_missing_and_placeholder_names(tmp_path): | |
| (tmp_path / ".gitignore").write_text(".env.*\n!.env.final.example\n", encoding="utf-8") | |
| env_path = tmp_path / ".env.final.local" | |
| env_path.write_text( | |
| "\n".join( | |
| [ | |
| "PROOFFRAME_STORAGE_BACKEND=b2", | |
| "PROOFFRAME_GENERATION_BACKEND=genblaze", | |
| "B2_ENDPOINT_URL=s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET=proofframe-demo-a6b4e49", | |
| "B2_KEY_ID=todo", | |
| "B2_APPLICATION_KEY=", | |
| "GENBLAZE_API_KEY=<paste-key>", | |
| "GENBLAZE_IMAGE_MODEL=seedream-5.0-lite", | |
| ] | |
| ) | |
| + "\n", | |
| encoding="utf-8", | |
| ) | |
| os.chmod(env_path, 0o644) | |
| report = final_env_wizard.build_check(tmp_path, env_path) | |
| assert report["env_file_mode_ok"] is False | |
| assert report["missing_required_names"] == [ | |
| "B2_KEY_ID", | |
| "B2_APPLICATION_KEY", | |
| "GENBLAZE_API_KEY", | |
| ] | |
| assert set(report["placeholder_names"]) >= { | |
| "B2_KEY_ID", | |
| "B2_APPLICATION_KEY", | |
| "GENBLAZE_API_KEY", | |
| } | |
| assert report["ready_for_live_entry"] is False | |
| def test_final_env_wizard_collects_from_env_and_mirrors_gmi_key(): | |
| values = final_env_wizard.collect_values( | |
| from_env=True, | |
| environ={ | |
| "B2_ENDPOINT_URL": "https://s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "proof-bucket", | |
| "B2_KEY_ID": "least-privilege-key-id", | |
| "B2_APPLICATION_KEY": "secret-b2-key", | |
| "GMI_API_KEY": "secret-gmi-key", | |
| }, | |
| ) | |
| assert values["PROOFFRAME_STORAGE_BACKEND"] == "b2" | |
| assert values["PROOFFRAME_GENERATION_BACKEND"] == "genblaze" | |
| assert values["GENBLAZE_API_KEY"] == "secret-gmi-key" | |
| assert values["GMI_API_KEY"] == "secret-gmi-key" | |
| assert values["GENBLAZE_IMAGE_MODEL"] == "seedream-5.0-lite" | |
| def test_final_env_wizard_refuses_missing_required_env(): | |
| with pytest.raises(ValueError, match="B2_ENDPOINT_URL"): | |
| final_env_wizard.collect_values(from_env=True, environ={}) | |
| def test_final_env_wizard_uses_existing_file_values_as_prompt_defaults(tmp_path): | |
| existing = tmp_path / ".env.final.local" | |
| existing.write_text( | |
| "\n".join( | |
| [ | |
| "PROOFFRAME_STORAGE_BACKEND=b2", | |
| "PROOFFRAME_GENERATION_BACKEND=genblaze", | |
| "B2_ENDPOINT_URL=s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET=proofframe-demo-a6b4e49", | |
| "B2_KEY_ID=existing-key-id", | |
| "B2_APPLICATION_KEY='existing b2 secret'", | |
| "GENBLAZE_API_KEY=existing-gmi-secret", | |
| "GENBLAZE_IMAGE_MODEL=seedream-5.0-lite", | |
| ] | |
| ) | |
| + "\n", | |
| encoding="utf-8", | |
| ) | |
| values = final_env_wizard.collect_values( | |
| from_env=False, | |
| initial_values=final_env_wizard.parse_env_file(existing), | |
| input_func=lambda prompt: "", | |
| secret_input=lambda prompt: "", | |
| ) | |
| assert values["B2_ENDPOINT_URL"] == "s3.us-west-004.backblazeb2.com" | |
| assert values["B2_BUCKET"] == "proofframe-demo-a6b4e49" | |
| assert values["B2_KEY_ID"] == "existing-key-id" | |
| assert values["B2_APPLICATION_KEY"] == "existing b2 secret" | |
| assert values["GENBLAZE_API_KEY"] == "existing-gmi-secret" | |
| assert "GMI_API_KEY" not in values | |
| def test_final_env_wizard_collects_missing_values_only_without_mirroring_provider_key(tmp_path): | |
| values, filled_names = final_env_wizard.collect_missing_values( | |
| initial_values={ | |
| "PROOFFRAME_STORAGE_BACKEND": "b2", | |
| "PROOFFRAME_GENERATION_BACKEND": "genblaze", | |
| "B2_ENDPOINT_URL": "s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "proofframe-demo-a6b4e49", | |
| "GENBLAZE_IMAGE_MODEL": "seedream-5.0-lite", | |
| }, | |
| input_func=lambda prompt: "least-privilege-key-id", | |
| secret_input=lambda prompt: ( | |
| "secret-b2-key" if "Backblaze" in prompt else "secret-gmi-key" | |
| ), | |
| ) | |
| summary = final_env_wizard.build_missing_only_success( | |
| tmp_path / ".env.final.local", | |
| values, | |
| filled_names, | |
| ) | |
| assert values["B2_KEY_ID"] == "least-privilege-key-id" | |
| assert values["B2_APPLICATION_KEY"] == "secret-b2-key" | |
| assert values["GENBLAZE_API_KEY"] == "secret-gmi-key" | |
| assert "GMI_API_KEY" not in values | |
| assert filled_names == [ | |
| "B2_KEY_ID", | |
| "B2_APPLICATION_KEY", | |
| "B2_APP_KEY", | |
| "GENBLAZE_API_KEY", | |
| ] | |
| assert "secret-b2-key" not in json.dumps(summary) | |
| assert "secret-gmi-key" not in json.dumps(summary) | |
| def test_final_env_wizard_missing_only_no_prompts_when_complete(): | |
| prompts: list[str] = [] | |
| values, filled_names = final_env_wizard.collect_missing_values( | |
| initial_values={ | |
| "PROOFFRAME_STORAGE_BACKEND": "b2", | |
| "PROOFFRAME_GENERATION_BACKEND": "genblaze", | |
| "B2_ENDPOINT_URL": "s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "proofframe-demo-a6b4e49", | |
| "B2_KEY_ID": "least-privilege-key-id", | |
| "B2_APPLICATION_KEY": "secret-b2-key", | |
| "GMI_API_KEY": "secret-gmi-key", | |
| "GENBLAZE_IMAGE_MODEL": "seedream-5.0-lite", | |
| }, | |
| input_func=lambda prompt: prompts.append(prompt) or "", | |
| secret_input=lambda prompt: prompts.append(prompt) or "", | |
| ) | |
| assert filled_names == [] | |
| assert values["GMI_API_KEY"] == "secret-gmi-key" | |
| assert prompts == [] | |
| def test_final_env_wizard_missing_only_preserves_extra_local_values(): | |
| values, filled_names = final_env_wizard.collect_missing_values( | |
| initial_values={ | |
| "PROOFFRAME_STORAGE_BACKEND": "b2", | |
| "PROOFFRAME_GENERATION_BACKEND": "genblaze", | |
| "B2_ENDPOINT_URL": "s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "proofframe-demo-a6b4e49", | |
| "GENBLAZE_IMAGE_MODEL": "seedream-5.0-lite", | |
| "PROOFFRAME_LOCAL_NOTE": "keep-me", | |
| }, | |
| input_func=lambda prompt: "least-privilege-key-id", | |
| secret_input=lambda prompt: ( | |
| "secret-b2-key" if "Backblaze" in prompt else "secret-gmi-key" | |
| ), | |
| ) | |
| rendered = final_env_wizard.render_env_file_preserving_extra(values) | |
| assert "PROOFFRAME_LOCAL_NOTE=keep-me" in rendered | |
| assert "# Preserved local-only values." in rendered | |
| assert "PROOFFRAME_LOCAL_NOTE" not in filled_names | |
| def test_final_env_wizard_missing_only_from_env_does_not_override_existing_values(): | |
| values, filled_names = final_env_wizard.collect_missing_values( | |
| initial_values={ | |
| "PROOFFRAME_STORAGE_BACKEND": "b2", | |
| "PROOFFRAME_GENERATION_BACKEND": "genblaze", | |
| "B2_ENDPOINT_URL": "s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "proofframe-demo-a6b4e49", | |
| "B2_KEY_ID": "existing-key-id", | |
| "GENBLAZE_IMAGE_MODEL": "seedream-5.0-lite", | |
| }, | |
| environ={ | |
| "B2_KEY_ID": "env-key-id", | |
| "B2_APPLICATION_KEY": "env-b2-secret", | |
| "GENBLAZE_API_KEY": "env-gmi-secret", | |
| }, | |
| input_func=lambda prompt: "", | |
| secret_input=lambda prompt: "", | |
| ) | |
| assert values["B2_KEY_ID"] == "existing-key-id" | |
| assert values["B2_APPLICATION_KEY"] == "env-b2-secret" | |
| assert values["GENBLAZE_API_KEY"] == "env-gmi-secret" | |
| assert "GMI_API_KEY" not in values | |
| assert filled_names == [] | |
| def test_final_env_wizard_environment_overrides_existing_defaults(tmp_path): | |
| existing = tmp_path / ".env.final.local" | |
| existing.write_text("B2_BUCKET=old-bucket\n", encoding="utf-8") | |
| values = final_env_wizard.collect_values( | |
| from_env=True, | |
| environ={ | |
| "B2_ENDPOINT_URL": "s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "env-bucket", | |
| "B2_KEY_ID": "env-key-id", | |
| "B2_APPLICATION_KEY": "env-b2-secret", | |
| "GENBLAZE_API_KEY": "env-gmi-secret", | |
| }, | |
| initial_values=final_env_wizard.parse_env_file(existing), | |
| ) | |
| assert values["B2_BUCKET"] == "env-bucket" | |
| def test_final_env_wizard_prefills_non_secret_b2_values(tmp_path): | |
| setup_path = tmp_path / "b2-live-setup.json" | |
| setup_path.write_text( | |
| json.dumps( | |
| { | |
| "safe_to_commit": True, | |
| "bucket_name": "proofframe-demo-a6b4e49", | |
| "endpoint": "s3.us-west-004.backblazeb2.com", | |
| } | |
| ), | |
| encoding="utf-8", | |
| ) | |
| values = final_env_wizard.non_secret_prefill_values(b2_setup_path=setup_path) | |
| summary = final_env_wizard.build_prefill_success(tmp_path / ".env.final.local", values) | |
| rendered = final_env_wizard.render_env_file(values) | |
| assert values["B2_BUCKET"] == "proofframe-demo-a6b4e49" | |
| assert values["B2_ENDPOINT_URL"] == "s3.us-west-004.backblazeb2.com" | |
| assert values["B2_REGION"] == "us-west-004" | |
| assert "B2_APPLICATION_KEY=" in rendered | |
| assert "GENBLAZE_API_KEY=" in rendered | |
| assert "B2_APPLICATION_KEY" in summary["missing_required_names"] | |
| assert "GENBLAZE_API_KEY" in summary["missing_secret_names"] | |
| assert "secret-b2-key" not in json.dumps(summary) | |
| assert "secret-gmi-key" not in json.dumps(summary) | |
| def test_final_env_wizard_writes_0600_and_does_not_print_values(tmp_path): | |
| path = tmp_path / ".env.final.local" | |
| values = { | |
| "PROOFFRAME_STORAGE_BACKEND": "b2", | |
| "PROOFFRAME_GENERATION_BACKEND": "genblaze", | |
| "B2_ENDPOINT_URL": "https://s3.us-west-004.backblazeb2.com", | |
| "B2_BUCKET": "proof-bucket", | |
| "B2_KEY_ID": "least-privilege-key-id", | |
| "B2_APPLICATION_KEY": "secret-b2-key", | |
| "GENBLAZE_API_KEY": "secret-gmi-key", | |
| "GMI_API_KEY": "secret-gmi-key", | |
| "GENBLAZE_IMAGE_MODEL": "seedream-5.0-lite", | |
| } | |
| content = final_env_wizard.render_env_file(values) | |
| final_env_wizard.write_env_file(path, content, force=False) | |
| summary = json.dumps(final_env_wizard.build_success(path, values)) | |
| assert path.exists() | |
| assert oct(os.stat(path).st_mode & 0o777) == "0o600" | |
| assert "secret-b2-key" in path.read_text(encoding="utf-8") | |
| assert "secret-b2-key" not in summary | |
| assert "secret-gmi-key" not in summary | |
| with pytest.raises(FileExistsError): | |
| final_env_wizard.write_env_file(path, content, force=False) | |