"""E2E tests for list_checklists MCP tool.
Scenarios from E2E Test Plan Section 5.3:
- Scenario 5.3.3: List Checklists Returns All Available (P0)
- Scenario 5.5.3: Dynamic Checklist Discovery (P1)
"""
from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING
import pytest
from sso_mcp_server.checklists.service import ChecklistService
if TYPE_CHECKING:
pass
@pytest.mark.e2e
@pytest.mark.smoke
@pytest.mark.checklist
class TestListChecklistsE2E:
"""E2E tests for list_checklists tool."""
def test_list_checklists_returns_all_available(
self,
e2e_checklist_dir: Path,
) -> None:
"""Scenario 5.3.3: List checklists returns all available.
Given server is authenticated and ready
And checklist directory contains: coding.md, architecture.md, detailed-design.md
When client sends MCP request to list_checklists
Then server returns array of all checklists with name and description
"""
# Arrange
service = ChecklistService(e2e_checklist_dir)
# Act
result = service.list_checklists()
# Assert
assert result is not None
assert len(result) == 3, f"Expected 3 checklists, got {len(result)}"
names = [c["name"] for c in result]
assert "Coding Standards" in names
assert "Architecture Review" in names
assert "Detailed Design" in names
# Each checklist should have name and description
for checklist in result:
assert "name" in checklist
assert "description" in checklist
def test_list_checklists_includes_descriptions(
self,
e2e_checklist_dir: Path,
) -> None:
"""Test that list_checklists includes descriptions from frontmatter.
Given checklists have YAML frontmatter with descriptions
When client requests list_checklists
Then each item includes the description
"""
# Arrange
service = ChecklistService(e2e_checklist_dir)
# Act
result = service.list_checklists()
# Assert
descriptions = {c["name"]: c["description"] for c in result}
assert descriptions["Coding Standards"] == "Quality checklist for code implementation"
assert descriptions["Architecture Review"] == "Architecture design checklist"
def test_list_checklists_does_not_include_content(
self,
e2e_checklist_dir: Path,
) -> None:
"""Test that list_checklists returns metadata only, not full content.
Given multiple checklists exist
When client requests list_checklists
Then response includes only name and description, not full content
"""
# Arrange
service = ChecklistService(e2e_checklist_dir)
# Act
result = service.list_checklists()
# Assert
for checklist in result:
# Should have name and description
assert "name" in checklist
assert "description" in checklist
# Should NOT have full content in list response
# (content is retrieved via get_checklist)
@pytest.mark.e2e
@pytest.mark.regression
@pytest.mark.checklist
class TestDynamicChecklistDiscoveryE2E:
"""E2E tests for dynamic checklist discovery."""
def test_dynamic_checklist_discovery(
self,
e2e_checklist_dir: Path,
) -> None:
"""Scenario 5.5.3: Dynamic checklist discovery.
Given server is running and authenticated
And initial list_checklists returns 3 checklists
When new file "custom.md" is added to CHECKLIST_DIR
And client sends list_checklists request
Then response includes 4 checklists (including "custom")
"""
# Arrange
service = ChecklistService(e2e_checklist_dir)
# Verify initial state
initial_result = service.list_checklists()
initial_count = len(initial_result)
assert initial_count == 3
# Add new checklist file
custom_content = """---
name: Custom Checklist
description: Dynamically added checklist
---
# Custom Checklist
- [ ] Custom item 1
"""
(e2e_checklist_dir / "custom.md").write_text(custom_content)
# Act - re-discover checklists
result = service.list_checklists()
# Assert
assert len(result) == 4, "Should discover newly added checklist"
names = [c["name"] for c in result]
assert "Custom Checklist" in names
def test_checklist_removal_detected(
self,
e2e_checklist_dir: Path,
) -> None:
"""Test that removed checklists are no longer listed.
Given server is running with 3 checklists
When a checklist file is deleted
Then list_checklists returns 2 checklists
"""
# Arrange
service = ChecklistService(e2e_checklist_dir)
# Verify initial state
initial_result = service.list_checklists()
assert len(initial_result) == 3
# Remove a checklist
(e2e_checklist_dir / "detailed-design.md").unlink()
# Act
result = service.list_checklists()
# Assert
assert len(result) == 2
names = [c["name"] for c in result]
assert "Detailed Design" not in names