Files
gurixandClaude 48d84bdc0a chore: archive add-pytest-tests change
Archive the completed pytest test suite implementation change. The change has been moved to the archive and the project-setup spec has been updated with all test requirements and scenarios.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 20:32:09 +01:00

12 KiB

project-setup Spec Delta

ADDED Requirements

Requirement: Automated Test Suite with Pytest

The project SHALL provide a comprehensive test suite using pytest to verify all features and prevent regressions.

Scenario: Run test suite successfully

  • GIVEN the project is set up with dependencies installed
  • WHEN the developer runs uv run pytest
  • THEN all tests SHALL execute
  • AND test results SHALL be displayed with pass/fail status
  • AND the command SHALL exit with code 0 if all tests pass

Scenario: Run tests with verbose output

  • GIVEN the project has tests implemented
  • WHEN the developer runs uv run pytest --verbose
  • THEN detailed test output SHALL be displayed
  • AND each test name and result SHALL be shown

Scenario: Run specific test categories

  • GIVEN tests are organized in subdirectories
  • WHEN the developer runs uv run pytest tests/unit
  • THEN only unit tests SHALL execute
  • WHEN the developer runs uv run pytest tests/integration
  • THEN only integration tests SHALL execute

Requirement: Test Organization Structure

Tests SHALL be organized in a clear directory structure separating different test types.

Scenario: Test directory structure exists

  • GIVEN the project repository
  • WHEN inspecting the directory structure
  • THEN a tests/ directory SHALL exist at the project root
  • AND subdirectories tests/unit/, tests/integration/, tests/e2e/, and tests/mcp/ SHALL exist
  • AND a tests/conftest.py file SHALL exist for shared fixtures

Scenario: Test files follow naming convention

  • GIVEN test files in the tests/ directory
  • WHEN examining file names
  • THEN all test files SHALL be named test_*.py
  • AND test file names SHALL correspond to the modules they test (e.g., test_validation.py for validation.py)

Requirement: Shared Test Fixtures

The test suite SHALL provide reusable fixtures for common test setup via conftest.py.

Scenario: Database fixture provides in-memory SQLite

  • GIVEN tests need database access
  • WHEN a test function requests the db fixture
  • THEN an in-memory SQLite database SHALL be created
  • AND the database SHALL have all tables created via Alembic migrations or direct schema creation
  • AND the database SHALL be cleaned up after the test completes

Scenario: Async session fixture provides database sessions

  • GIVEN tests need to interact with the database
  • WHEN a test function requests the async_session fixture
  • THEN an async SQLAlchemy session SHALL be provided
  • AND the session SHALL be connected to the test database
  • AND the session SHALL be closed after the test completes

Scenario: GraphQL client fixture provides test client

  • GIVEN tests need to make GraphQL requests
  • WHEN a test function requests the graphql_client fixture
  • THEN a FastAPI test client SHALL be provided
  • AND the client SHALL be configured to use the test database
  • AND the client SHALL support async GraphQL queries and mutations

Requirement: Unit Tests for Validation Logic

Unit tests SHALL verify validation functions work correctly with valid and invalid inputs.

Scenario: Test firstName validation with valid input

  • GIVEN a valid firstName "Alice"
  • WHEN validate_first_name("Alice") is called
  • THEN no exception SHALL be raised

Scenario: Test firstName validation with empty string

  • GIVEN an empty firstName ""
  • WHEN validate_first_name("") is called
  • THEN a ValidationError SHALL be raised
  • AND the error message SHALL indicate firstName cannot be empty

Scenario: Test email validation with valid email

  • GIVEN a valid email "test@example.com"
  • WHEN validate_email("test@example.com") is called
  • THEN no exception SHALL be raised

Scenario: Test email validation with invalid email

  • GIVEN an invalid email "not-an-email"
  • WHEN validate_email("not-an-email") is called
  • THEN a ValidationError SHALL be raised
  • AND the error message SHALL indicate invalid email format

Scenario: Test email validation with None

  • GIVEN email is None
  • WHEN validate_email(None) is called
  • THEN no exception SHALL be raised (None is allowed)

Scenario: Test phone validation with valid E.164 number

  • GIVEN a valid phone "+41791234567"
  • WHEN validate_phone("+41791234567") is called
  • THEN no exception SHALL be raised

Scenario: Test phone validation with invalid number

  • GIVEN an invalid phone "123"
  • WHEN validate_phone("123") is called
  • THEN a ValidationError SHALL be raised

Scenario: Test phone validation with None

  • GIVEN phone is None
  • WHEN validate_phone(None) is called
  • THEN no exception SHALL be raised (None is allowed)

Requirement: Integration Tests for Member Model

Integration tests SHALL verify database operations with the Member model.

Scenario: Create member with minimal data

  • GIVEN a test database session
  • WHEN a Member is created with only firstName="Alice"
  • THEN the member SHALL be persisted to the database
  • AND the member SHALL have an auto-generated ID
  • AND created_at and updated_at timestamps SHALL be populated
  • AND all optional fields SHALL be None

Scenario: Create member with complete data

  • GIVEN a test database session
  • WHEN a Member is created with all fields populated
  • THEN the member SHALL be persisted with all data
  • AND all fields SHALL match the provided values

Scenario: Member timestamps are set correctly

  • GIVEN a newly created member
  • THEN created_at SHALL be set to current time
  • AND updated_at SHALL be set to current time
  • AND created_at SHALL equal updated_at for new members

Requirement: Integration Tests for GraphQL Queries

Integration tests SHALL verify GraphQL query resolvers return correct data.

Scenario: Query single member by ID

  • GIVEN a member exists with ID 1
  • WHEN the member(id: 1) query is executed
  • THEN the member data SHALL be returned
  • AND all requested fields SHALL match the database record

Scenario: Query member with non-existent ID

  • GIVEN no member exists with ID 999
  • WHEN the member(id: 999) query is executed
  • THEN None SHALL be returned
  • AND no error SHALL be raised

Scenario: List all members

  • GIVEN multiple members exist in the database
  • WHEN the members query is executed
  • THEN an array of all members SHALL be returned
  • AND members SHALL be sorted by last_name (nulls last), then first_name

Scenario: List members when database is empty

  • GIVEN no members exist in the database
  • WHEN the members query is executed
  • THEN an empty array SHALL be returned

Requirement: Integration Tests for GraphQL Mutations

Integration tests SHALL verify GraphQL mutation resolvers create, update, and delete members correctly.

Scenario: Create member with minimal data

  • GIVEN CreateMemberInput with only firstName="Bob"
  • WHEN the createMember mutation is executed
  • THEN a new member SHALL be created in the database
  • AND the member SHALL have firstName="Bob"
  • AND all optional fields SHALL be None
  • AND the mutation SHALL return the created member with ID

Scenario: Create member with complete data

  • GIVEN CreateMemberInput with all fields populated
  • WHEN the createMember mutation is executed
  • THEN a new member SHALL be created with all data
  • AND all fields SHALL match the input

Scenario: Create member with invalid email

  • GIVEN CreateMemberInput with email="not-an-email"
  • WHEN the createMember mutation is executed
  • THEN a ValidationError SHALL be raised
  • AND no database record SHALL be created

Scenario: Update member successfully

  • GIVEN a member exists with ID 1
  • WHEN the updateMember mutation is executed with id=1 and email="new@example.com"
  • THEN the member's email SHALL be updated to "new@example.com"
  • AND the updated_at timestamp SHALL be refreshed
  • AND all other fields SHALL remain unchanged

Scenario: Update member with non-existent ID

  • GIVEN no member exists with ID 999
  • WHEN the updateMember mutation is executed with id=999
  • THEN a MemberNotFoundError SHALL be raised
  • AND the error message SHALL indicate member not found

Scenario: Delete member successfully

  • GIVEN a member exists with ID 1
  • WHEN the deleteMember mutation is executed with id=1
  • THEN the member SHALL be removed from the database
  • AND the mutation SHALL return true
  • AND subsequent queries for that member SHALL return None

Scenario: Delete member with non-existent ID

  • GIVEN no member exists with ID 999
  • WHEN the deleteMember mutation is executed with id=999
  • THEN a MemberNotFoundError SHALL be raised

Requirement: E2E Tests for GraphQL API

End-to-end tests SHALL verify complete GraphQL request/response flows over HTTP.

Scenario: Execute GraphQL query via HTTP POST

  • GIVEN the FastAPI application with GraphQL endpoint
  • WHEN a POST request is sent to /graphql with a query
  • THEN the query SHALL be executed
  • AND a JSON response SHALL be returned with data or errors

Scenario: GraphQL introspection query

  • GIVEN the GraphQL API is running
  • WHEN an introspection query for __schema is executed
  • THEN the complete schema SHALL be returned
  • AND all types, queries, and mutations SHALL be included

Scenario: GraphQL type introspection

  • GIVEN the GraphQL API is running
  • WHEN an introspection query for __type(name: "Member") is executed
  • THEN the Member type definition SHALL be returned
  • AND all fields with their types SHALL be included

Requirement: MCP Server Tests

Tests SHALL verify MCP server tool definitions and execution.

Scenario: MCP server initializes successfully

  • GIVEN a valid CLUBBER_API_URL
  • WHEN the MCP server is instantiated
  • THEN the server SHALL initialize without errors
  • AND the GraphQL client SHALL be configured

Scenario: List tools returns all 6 tools

  • GIVEN an initialized MCP server
  • WHEN list_tools() is called
  • THEN 6 tools SHALL be returned
  • AND tools SHALL include: list_members, get_member, create_member, update_member, get_graphql_schema, execute_graphql_query

Scenario: Execute list_members tool

  • GIVEN members exist in the database
  • WHEN the list_members tool is invoked
  • THEN a formatted list of all members SHALL be returned

Scenario: Execute get_member tool

  • GIVEN a member exists with ID 1
  • WHEN the get_member tool is invoked with id=1
  • THEN the member's data SHALL be returned as formatted text

Scenario: Execute create_member tool

  • GIVEN valid member input data
  • WHEN the create_member tool is invoked
  • THEN a new member SHALL be created via the GraphQL API
  • AND the created member data SHALL be returned

Scenario: Execute get_graphql_schema tool

  • GIVEN the GraphQL API is accessible
  • WHEN the get_graphql_schema tool is invoked
  • THEN the complete schema SHALL be retrieved via introspection
  • AND formatted schema information SHALL be returned

Scenario: Execute execute_graphql_query tool with simple query

  • GIVEN a valid GraphQL query string
  • WHEN the execute_graphql_query tool is invoked
  • THEN the query SHALL be executed against the API
  • AND formatted JSON results SHALL be returned

Scenario: Execute execute_graphql_query tool with variables

  • GIVEN a GraphQL query with variables
  • WHEN the execute_graphql_query tool is invoked with query and variables
  • THEN the query SHALL be executed with variable substitution
  • AND results SHALL be returned

Requirement: Test Documentation in README

The README SHALL document how to run tests and understand test organization.

Scenario: README contains test running instructions

  • GIVEN the README.md file
  • WHEN reading the documentation
  • THEN a "Running Tests" section SHALL exist
  • AND the section SHALL document the uv run pytest command
  • AND examples of running specific test categories SHALL be provided

Scenario: README documents test organization

  • GIVEN the README.md file
  • WHEN reading the documentation
  • THEN a "Test Organization" section SHALL exist
  • AND the section SHALL explain the tests/ directory structure
  • AND the section SHALL describe unit, integration, e2e, and mcp test categories