"""Unit tests for storage layer."""
import tempfile
from pathlib import Path
from uuid import uuid4
import pytest
from domin8.storage import (
atomic_write,
compute_artifact_hash,
create_artifact_uuid,
get_artifact_dir,
get_current_timestamp,
read_json,
verify_artifact,
write_json_atomic,
)
def test_atomic_write(tmp_path):
"""Test atomic file writing."""
file_path = tmp_path / "test.txt"
content = "Hello, World!"
atomic_write(file_path, content)
assert file_path.exists()
assert file_path.read_text() == content
def test_write_json_atomic(tmp_path):
"""Test atomic JSON writing with canonical formatting."""
file_path = tmp_path / "test.json"
data = {"b": 2, "a": 1, "c": 3}
write_json_atomic(file_path, data)
assert file_path.exists()
# Check canonical format: sorted keys
content = file_path.read_text()
assert content == '{"a":1,"b":2,"c":3}'
def test_read_json(tmp_path):
"""Test JSON reading."""
file_path = tmp_path / "test.json"
data = {"key": "value"}
write_json_atomic(file_path, data)
result = read_json(file_path)
assert result == data
def test_create_artifact_uuid():
"""Test UUID creation."""
uuid1 = create_artifact_uuid()
uuid2 = create_artifact_uuid()
assert uuid1 != uuid2
assert isinstance(uuid1, type(uuid4()))
def test_get_current_timestamp():
"""Test timestamp generation."""
timestamp = get_current_timestamp()
# Should be ISO8601 format
assert "T" in timestamp
assert ":" in timestamp
# Should have timezone info (+ or - for offset, or Z for UTC)
assert "+" in timestamp or "-" in timestamp or "Z" in timestamp
def test_compute_artifact_hash(tmp_path):
"""Test artifact hash computation."""
# Create minimal artifact structure
artifact_dir = tmp_path / "artifact"
artifact_dir.mkdir()
write_json_atomic(artifact_dir / "meta.json", {"test": "meta"})
write_json_atomic(artifact_dir / "intent.json", {"test": "intent"})
atomic_write(artifact_dir / "diff.patch", "some diff content")
# Compute hash
hash1 = compute_artifact_hash(artifact_dir)
assert isinstance(hash1, str)
assert len(hash1) == 64 # SHA-256 hex digest
# Same content should produce same hash
hash2 = compute_artifact_hash(artifact_dir)
assert hash1 == hash2
def test_verify_artifact(tmp_path):
"""Test artifact verification."""
artifact_dir = tmp_path / "artifact"
artifact_dir.mkdir()
write_json_atomic(artifact_dir / "meta.json", {"test": "meta"})
write_json_atomic(artifact_dir / "intent.json", {"test": "intent"})
atomic_write(artifact_dir / "diff.patch", "diff content")
# Compute and store hash
hash_value = compute_artifact_hash(artifact_dir)
atomic_write(artifact_dir / "verification.sha256", hash_value)
# Verify should pass
assert verify_artifact(artifact_dir)
# Tamper with a file
write_json_atomic(artifact_dir / "meta.json", {"test": "tampered"})
# Verify should fail
assert not verify_artifact(artifact_dir)