|
|
|
@@ -0,0 +1,224 @@
|
|
|
|
|
"""Step definitions for documentation showcase metadata refresh tests.
|
|
|
|
|
|
|
|
|
|
Tests for features/docs_showcase_metadata_refresh.feature — validates that
|
|
|
|
|
the actor management showcase metadata is correctly refreshed in examples.json.
|
|
|
|
|
|
|
|
|
|
All file operations use a temporary copy of examples.json to avoid modifying
|
|
|
|
|
the actual repository file during test execution.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
import re
|
|
|
|
|
import shutil
|
|
|
|
|
import tempfile
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from typing import Any
|
|
|
|
|
|
|
|
|
|
from behave import given, then, when # type: ignore[import-untyped]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@given('the showcase examples JSON file exists at "{path}"')
|
|
|
|
|
def step_showcase_json_exists(context: Any, path: str) -> None:
|
|
|
|
|
"""Verify the showcase examples JSON file exists and create a temp copy."""
|
|
|
|
|
source_path = Path(path)
|
|
|
|
|
assert source_path.exists(), f"File {path} does not exist"
|
|
|
|
|
# Create a temp copy for testing to avoid modifying the actual repository file.
|
|
|
|
|
# This also prevents race conditions in parallel test execution.
|
|
|
|
|
temp_dir = tempfile.mkdtemp(prefix="cleveragents_showcase_test_")
|
|
|
|
|
temp_file = Path(temp_dir) / source_path.name
|
|
|
|
|
shutil.copy2(source_path, temp_file)
|
|
|
|
|
context.examples_file = temp_file
|
|
|
|
|
if not hasattr(context, "_cleanup_handlers"):
|
|
|
|
|
context._cleanup_handlers = []
|
|
|
|
|
context._cleanup_handlers.append(
|
|
|
|
|
lambda: shutil.rmtree(temp_dir, ignore_errors=True)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@given("the examples.json file has an actor management showcase entry")
|
|
|
|
|
def step_has_actor_management_entry(context: Any) -> None:
|
|
|
|
|
"""Verify the examples.json has an actor management entry."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
actor_mgmt_entry = None
|
|
|
|
|
for example in data.get("examples", []):
|
|
|
|
|
if "actor-management" in example.get("path", ""):
|
|
|
|
|
actor_mgmt_entry = example
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
assert actor_mgmt_entry is not None, "Actor management entry not found"
|
|
|
|
|
context.actor_mgmt_entry = actor_mgmt_entry
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@when("I refresh the actor management showcase metadata")
|
|
|
|
|
def step_refresh_metadata(context: Any) -> None:
|
|
|
|
|
"""Refresh the actor management showcase metadata in the temp copy."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
# Update the last_updated field
|
|
|
|
|
data["last_updated"] = "2026-04-19"
|
|
|
|
|
|
|
|
|
|
# Update the actor management showcase entry
|
|
|
|
|
for example in data["examples"]:
|
|
|
|
|
if "actor-management" in example["path"]:
|
|
|
|
|
example["generated_at"] = "2026-04-19"
|
|
|
|
|
|
|
|
|
|
# Write back to the temp copy (not the actual repository file)
|
|
|
|
|
with open(context.examples_file, "w") as f:
|
|
|
|
|
json.dump(data, f, indent=2)
|
|
|
|
|
|
|
|
|
|
context.updated_data = data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then('the generated_at field should be updated to "{date}"')
|
|
|
|
|
def step_generated_at_updated(context: Any, date: str) -> None:
|
|
|
|
|
"""Verify the generated_at field is updated."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
for example in data["examples"]:
|
|
|
|
|
if "actor-management" in example["path"]:
|
|
|
|
|
assert example["generated_at"] == date, (
|
|
|
|
|
f"Expected {date}, got {example['generated_at']}"
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
raise AssertionError("Actor management entry not found")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then('the last_updated field should be set to "{date}"')
|
|
|
|
|
def step_last_updated_set(context: Any, date: str) -> None:
|
|
|
|
|
"""Verify the last_updated field is set."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
assert data["last_updated"] == date, f"Expected {date}, got {data['last_updated']}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the JSON file should remain valid")
|
|
|
|
|
def step_json_valid(context: Any) -> None:
|
|
|
|
|
"""Verify the JSON file is valid."""
|
|
|
|
|
try:
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
json.load(f)
|
|
|
|
|
except json.JSONDecodeError as e:
|
|
|
|
|
raise AssertionError(f"Invalid JSON: {e}") from e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@given("the examples.json file is loaded")
|
|
|
|
|
def step_load_examples_json(context: Any) -> None:
|
|
|
|
|
"""Load the examples.json file."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
context.examples_data = json.load(f)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@when("I check the last_updated field")
|
|
|
|
|
def step_check_last_updated(context: Any) -> None:
|
|
|
|
|
"""Check the last_updated field."""
|
|
|
|
|
context.last_updated = context.examples_data.get("last_updated")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the last_updated field should not be null")
|
|
|
|
|
def step_last_updated_not_null(context: Any) -> None:
|
|
|
|
|
"""Verify last_updated is not null."""
|
|
|
|
|
assert context.last_updated is not None, "last_updated field is null"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the last_updated field should be a valid date string")
|
|
|
|
|
def step_last_updated_valid_date(context: Any) -> None:
|
|
|
|
|
"""Verify last_updated is a valid date string."""
|
|
|
|
|
pattern = r"^\d{4}-\d{2}-\d{2}$"
|
|
|
|
|
assert re.match(pattern, context.last_updated), (
|
|
|
|
|
f"Invalid date format: {context.last_updated}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then('the last_updated field should match format "{format_str}"')
|
|
|
|
|
def step_last_updated_format(context: Any, format_str: str) -> None:
|
|
|
|
|
"""Verify last_updated matches the expected format."""
|
|
|
|
|
# Already verified by step_last_updated_valid_date
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@when("I find the actor management showcase entry")
|
|
|
|
|
def step_find_actor_mgmt_entry(context: Any) -> None:
|
|
|
|
|
"""Find the actor management showcase entry."""
|
|
|
|
|
for example in context.examples_data["examples"]:
|
|
|
|
|
if "actor-management" in example.get("path", ""):
|
|
|
|
|
context.actor_mgmt_entry = example
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
raise AssertionError("Actor management entry not found")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the entry should have a generated_at field")
|
|
|
|
|
def step_entry_has_generated_at(context: Any) -> None:
|
|
|
|
|
"""Verify the entry has a generated_at field."""
|
|
|
|
|
assert "generated_at" in context.actor_mgmt_entry, "generated_at field not found"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then('the generated_at field should be "{date}"')
|
|
|
|
|
def step_generated_at_is(context: Any, date: str) -> None:
|
|
|
|
|
"""Verify the generated_at field value."""
|
|
|
|
|
assert context.actor_mgmt_entry["generated_at"] == date, (
|
|
|
|
|
f"Expected {date}, got {context.actor_mgmt_entry['generated_at']}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then('the entry title should contain "{text}"')
|
|
|
|
|
def step_entry_title_contains(context: Any, text: str) -> None:
|
|
|
|
|
"""Verify the entry title contains text."""
|
|
|
|
|
title = context.actor_mgmt_entry.get("title", "")
|
|
|
|
|
assert text in title, f"Title does not contain '{text}': {title}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then('the entry path should contain "{text}"')
|
|
|
|
|
def step_entry_path_contains(context: Any, text: str) -> None:
|
|
|
|
|
"""Verify the entry path contains text."""
|
|
|
|
|
path = context.actor_mgmt_entry.get("path", "")
|
|
|
|
|
assert text in path, f"Path does not contain '{text}': {path}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the output format showcase entry should remain unchanged")
|
|
|
|
|
def step_output_format_unchanged(context: Any) -> None:
|
|
|
|
|
"""Verify the output format entry is unchanged."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
for example in data["examples"]:
|
|
|
|
|
if "output-format" in example.get("path", ""):
|
|
|
|
|
assert example["generated_at"] == "2026-04-07", (
|
|
|
|
|
"Output format entry was modified"
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
raise AssertionError("Output format entry not found")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the server integration showcase entry should remain unchanged")
|
|
|
|
|
def step_server_integration_unchanged(context: Any) -> None:
|
|
|
|
|
"""Verify the server integration entry is unchanged."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
for example in data["examples"]:
|
|
|
|
|
if "server-and-a2a" in example.get("path", ""):
|
|
|
|
|
assert example["generated_at"] == "2026-04-07", (
|
|
|
|
|
"Server integration entry was modified"
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
raise AssertionError("Server integration entry not found")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@then("the total number of examples should remain {count:d}")
|
|
|
|
|
def step_total_examples_count(context: Any, count: int) -> None:
|
|
|
|
|
"""Verify the total number of examples."""
|
|
|
|
|
with open(context.examples_file) as f:
|
|
|
|
|
data = json.load(f)
|
|
|
|
|
|
|
|
|
|
assert len(data["examples"]) == count, (
|
|
|
|
|
f"Expected {count} examples, got {len(data['examples'])}"
|
|
|
|
|
)
|