WordPress MCP Plugin Testing Framework

June 10, 2025 · View on GitHub

This directory contains the testing framework for the WordPress MCP plugin. It covers transport protocols (STDIO and Streamable), authentication methods, and MCP tool functionalities.

Test Structure

The main tests are located in the phpunit directory.

Base Test Class

  • McpTransportTestBase.php - Abstract base class providing common functionality for transport testing:
    • JWT token generation and management
    • Authentication helpers (JWT and Application Password)
    • Common assertion methods
    • Data providers for testing scenarios

Transport-Specific Tests

  • McpStdioTransportTest.php - Tests for STDIO transport protocol:

    • WordPress-style responses (WP_REST_Response/WP_Error)
    • Both JWT and Application Password authentication
    • Backward compatibility testing
    • Permission validation using is_user_logged_in()
  • McpStreamableTransportTest.php - Tests for Streamable transport protocol:

    • JSON-RPC 2.0 format validation
    • JWT-only authentication (rejects Application Passwords)
    • Header validation (Accept, Content-Type)
    • Batch request handling
    • Notification handling (requests without ID)
    • Permission validation using current_user_can('manage_options')

Integration Tests

  • McpTransportIntegrationTest.php - Comparative testing of both transports:
    • Side-by-side authentication testing
    • Response format comparisons
    • Error handling differences
    • Protocol requirement validation

Authentication Tests (JwtAuthTest.php)

This test suite provides comprehensive coverage for all JWT authentication functionality.

Token Generation Tests

  • test_generate_token_with_valid_credentials - Valid username/password authentication
  • test_generate_token_with_invalid_credentials - Invalid credentials handling
  • test_generate_token_with_custom_expiration - Custom token expiration time
  • test_generate_token_with_invalid_expiration - Invalid expiration parameters
  • test_generate_token_for_logged_in_user - Token generation for authenticated users
  • test_generate_token_without_credentials_not_logged_in - Missing credentials error

Authentication Flow Tests

  • test_token_validation - Valid token authentication
  • test_authentication_with_invalid_token - Invalid token handling
  • test_authentication_with_missing_header - Missing Authorization header
  • test_authentication_not_applied_to_non_mcp_endpoints - Selective authentication
  • test_authentication_with_revoked_token - Revoked token handling
  • test_authentication_with_non_existent_user - Deleted user scenarios
  • test_authentication_with_malformed_token - Malformed JWT handling
  • test_authentication_with_expired_token - Token expiration
  • test_authentication_with_different_auth_header_formats - Header format validation

Token Management Tests

  • test_token_revocation - Token revocation functionality
  • test_token_revocation_with_missing_jti - Missing JTI parameter
  • test_token_revocation_with_non_existent_jti - Non-existent token handling
  • test_list_tokens - Token listing functionality
  • test_list_tokens_removes_expired_tokens - Automatic cleanup
  • test_permission_check_for_token_management - Permission validation

System Tests

  • test_jwt_routes_are_registered - REST API route registration
  • test_jwt_secret_key_generation - Automatic secret key generation

Authentication Matrix

TransportJWTApplication PasswordUser Role Required
STDIOAny authenticated
StreamableAdministrator

Key Differences Between Transports

STDIO Transport (/wp/v2/wpmcp)

  • Authentication: is_user_logged_in() - accepts both JWT and Application Password
  • Response Format: WordPress-style (WP_REST_Response for success, WP_Error for errors)
  • Request Format: Simple {method, params} structure
  • Headers: Basic Content-Type: application/json
  • Backward Compatibility: Supports legacy request formats
  • User Permissions: Any authenticated user

Streamable Transport (/wp/v2/wpmcp/streamable)

  • Authentication: JWT only with current_user_can('manage_options')
  • Response Format: JSON-RPC 2.0 ({jsonrpc, id, result} or {jsonrpc, id, error})
  • Request Format: Strict JSON-RPC 2.0 {jsonrpc: "2.0", id, method, params}
  • Headers: Requires Accept: application/json, text/event-stream
  • Batch Support: Handles arrays of requests
  • Notifications: Supports requests without ID (returns 202)
  • User Permissions: Administrator only

Running Tests

Individual Test Classes

# Test STDIO transport
vendor/bin/phpunit wp-content/plugins/wordpress-mcp/tests/phpunit/McpStdioTransportTest.php

# Test Streamable transport
vendor/bin/phpunit wp-content/plugins/wordpress-mcp/tests/phpunit/McpStreamableTransportTest.php

# Test integration between transports
vendor/bin/phpunit wp-content/plugins/wordpress-mcp/tests/phpunit/McpTransportIntegrationTest.php

# Test JWT authentication
vendor/bin/phpunit wp-content/plugins/wordpress-mcp/tests/phpunit/JwtAuthTest.php

To run a specific test method in the JWT suite:

vendor/bin/phpunit tests/phpunit/JwtAuthTest.php --filter test_generate_token_with_valid_credentials

Run Test Suites

# Run all Transport tests
vendor/bin/phpunit wp-content/plugins/wordpress-mcp/tests/phpunit/ --filter="Mcp.*Transport"

# Run all Authentication tests
vendor/bin/phpunit wp-content/plugins/wordpress-mcp/tests/phpunit/ --filter=".*Auth"

Test Coverage

Authentication Testing

  • ✅ JWT authentication for both transports
  • ✅ Application Password authentication (STDIO only)
  • ✅ Authentication rejection scenarios
  • ✅ User role and capability validation
  • ✅ Token validation and expiration
  • ✅ Authentication fallback behavior

Protocol Testing

  • ✅ Request format validation
  • ✅ Response format validation
  • ✅ Header requirement validation
  • ✅ HTTP method restrictions
  • ✅ Error response formats
  • ✅ Batch request handling (Streamable)
  • ✅ Notification handling (Streamable)

Integration Testing

  • ✅ Cross-transport comparison
  • ✅ Same MCP methods on both transports
  • ✅ Authentication method differences
  • ✅ Response format differences
  • ✅ Error handling consistency
  • ✅ MCP enable/disable behavior

Edge Case Testing

  • ✅ Malformed JSON handling
  • ✅ Large request handling
  • ✅ Invalid authentication scenarios
  • ✅ Missing required headers
  • ✅ CORS header validation
  • ✅ OPTIONS preflight handling

Extending the Tests

Adding New Transport Tests

  1. Extend McpTransportTestBase
  2. Implement abstract methods:
    • get_transport_endpoint()
    • create_transport_request()
    • assert_valid_response()
    • assert_error_response()

Adding New MCP Method Tests

Use the existing tool tests as templates:

  • McpPostsToolsTest.php
  • McpMediaToolsTest.php
  • McpUsersToolsTest.php
  • etc.

Testing Custom Authentication

The base class provides helpers for:

  • JWT token generation
  • Application Password creation
  • Authentication state management
  • Server global cleanup

Test Environment

The tests use WordPress's unit testing framework and require:

  • PHP 7.4+
  • WordPress test environment
  • PHPUnit 9.x
  • Firebase JWT library

All test data (e.g., users) is automatically cleaned up after each test run.

Best Practices

  1. Always clean up authentication state between tests using clean_server_globals()
  2. Use appropriate assertion methods for each transport type
  3. Test both success and error scenarios for all methods
  4. Validate response formats specific to each transport
  5. Test authentication edge cases like expired tokens and invalid users
  6. Use data providers for testing multiple scenarios efficiently

Troubleshooting

Common Issues

  • Linter Errors: The static analysis tool shows false positives for WordPress/PHPUnit classes that exist at runtime.
  • Authentication Failures: Ensure JWT tokens are properly generated and server globals are set correctly.
  • Header Validation: Streamable transport requires specific Accept headers.
  • Permission Issues: Remember that Streamable requires manage_options capability.

Debug Tips

  • Use error_log() to debug request/response data.
  • Check that MCP is enabled with get_option('wpmcp_enabled').
  • Verify user roles and capabilities in test setup.
  • Ensure REST API is properly initialized with do_action('rest_api_init').

For more information about WordPress testing, see the WordPress Testing Documentation.