"""Tests for JSON config file resource."""
from pathlib import Path
import pytest
from pragma_sdk.provider import ProviderHarness
from jsonstore_provider import ConfigFile, ConfigFileConfig, ConfigFileOutputs
@pytest.fixture
def harness() -> ProviderHarness:
"""Test harness for invoking lifecycle methods."""
return ProviderHarness()
@pytest.fixture
def test_dir(tmp_path: Path) -> str:
"""Temporary directory for test files."""
return str(tmp_path)
async def test_create_config_file(harness: ProviderHarness, test_dir: str) -> None:
"""on_create writes JSON file and returns outputs."""
config = ConfigFileConfig(
filename="app.json",
directory=test_dir,
data={"debug": True, "port": 8080},
)
result = await harness.invoke_create(ConfigFile, name="app-config", config=config)
assert result.success
assert result.outputs is not None
assert result.outputs.file_path == f"{test_dir}/app.json"
assert result.outputs.size_bytes > 0
# Verify file was created with correct content
path = Path(result.outputs.file_path)
assert path.exists()
assert '"debug": true' in path.read_text()
async def test_update_changes_content(harness: ProviderHarness, test_dir: str) -> None:
"""on_update rewrites file when data changes."""
initial_config = ConfigFileConfig(
filename="app.json",
directory=test_dir,
data={"version": 1},
)
updated_config = ConfigFileConfig(
filename="app.json",
directory=test_dir,
data={"version": 2},
)
# Create initial file
create_result = await harness.invoke_create(
ConfigFile, name="app-config", config=initial_config
)
assert create_result.success
initial_hash = create_result.outputs.content_hash
# Update the file
update_result = await harness.invoke_update(
ConfigFile,
name="app-config",
config=updated_config,
previous_config=initial_config,
current_outputs=create_result.outputs,
)
assert update_result.success
assert update_result.outputs.content_hash != initial_hash
# Verify content changed
path = Path(update_result.outputs.file_path)
assert '"version": 2' in path.read_text()
async def test_update_moves_file(harness: ProviderHarness, test_dir: str) -> None:
"""on_update moves file when path changes."""
initial_config = ConfigFileConfig(
filename="old.json",
directory=test_dir,
data={"key": "value"},
)
updated_config = ConfigFileConfig(
filename="new.json",
directory=test_dir,
data={"key": "value"},
)
# Create initial file
create_result = await harness.invoke_create(
ConfigFile, name="config", config=initial_config
)
# Update with new filename
update_result = await harness.invoke_update(
ConfigFile,
name="config",
config=updated_config,
previous_config=initial_config,
current_outputs=create_result.outputs,
)
assert update_result.success
assert not Path(test_dir, "old.json").exists()
assert Path(test_dir, "new.json").exists()
async def test_delete_removes_file(harness: ProviderHarness, test_dir: str) -> None:
"""on_delete removes the file."""
config = ConfigFileConfig(
filename="temp.json",
directory=test_dir,
data={"temporary": True},
)
# Create then delete
create_result = await harness.invoke_create(ConfigFile, name="temp", config=config)
file_path = Path(create_result.outputs.file_path)
assert file_path.exists()
delete_result = await harness.invoke_delete(
ConfigFile,
name="temp",
config=config,
current_outputs=create_result.outputs,
)
assert delete_result.success
assert not file_path.exists()
async def test_delete_idempotent(harness: ProviderHarness, test_dir: str) -> None:
"""on_delete succeeds even if file doesn't exist."""
config = ConfigFileConfig(
filename="nonexistent.json",
directory=test_dir,
data={},
)
# Delete without creating - should not raise
result = await harness.invoke_delete(ConfigFile, name="ghost", config=config)
assert result.success