MikoPBX API Test Generating Generate comprehensive Python pytest tests for MikoPBX REST API endpoints with full parameter coverage, schema validation, and edge case testing. What This Skill Does Analyzes DataStructure.php files and generates complete pytest test suites including: - ✅ CRUD operation tests (Create, Read, Update, Delete) - ✅ Positive and negative test cases - ✅ Parameter validation tests - ✅ Edge cases and boundary conditions - ✅ Schema validation tests - ✅ Proper fixtures and authentication - ✅ Detailed assertions with error messages When to Use This Skill Use this skill when y…

, // Regex pattern\n 'minLength' => 1, // Min length\n 'maxLength' => 100, // Max length\n ],\n ],\n ],\n ];\n}\n```\n\n### Use This Data To\n\n1. **Generate valid payloads** - Use `example` and `default` values\n2. **Test required fields** - Create tests omitting each required field\n3. **Test data types** - Create tests with wrong types\n4. **Test enums** - Create tests for each enum value and invalid values\n5. **Test patterns** - Create tests for valid/invalid patterns\n6. **Test boundaries** - Create tests for min/max values\n\n## Test Documentation Template\n\nAdd to the top of each test file:\n\n```python\n\"\"\"\nTests for {ResourceName} API endpoint\n\nAPI Endpoint: /pbxcore/api/v3/{resource-path}\nDataStructure: src/PBXCoreREST/Lib/{ResourceName}/DataStructure.php\n\nTest Coverage:\n- CRUD operations (Create, Read, Update, Delete)\n- Required vs optional parameters\n- Data type validations\n- Enum value validations\n- Pattern validations (regex)\n- Boundary conditions (min/max values)\n- Special characters and edge cases\n- Schema validation (when SCHEMA_VALIDATION_STRICT=1)\n\nRequirements:\n- pytest\n- requests\n- Docker container running with MikoPBX\n\nRun tests:\n pytest tests/api/test_{resource_name}.py -v\n\nRun with schema validation:\n # Ensure SCHEMA_VALIDATION_STRICT=1 is set in container\n pytest tests/api/test_{resource_name}.py -v\n\"\"\"\n```\n\n## Output Format\n\nAlways generate:\n\n1. ✅ **Complete pytest file** - Runnable without modifications\n2. ✅ **Documentation block** - Clear description at the top\n3. ✅ **All test classes** - CRUD, schema validation, edge cases\n4. ✅ **Proper fixtures** - Authentication and headers\n5. ✅ **Clear assertions** - With descriptive error messages\n6. ✅ **Comments** - Explaining complex validations\n\n## Running Tests\n\n### Basic Execution\n\n```bash\n# Run all API tests\npytest tests/api/ -v\n\n# Run specific endpoint tests\npytest tests/api/test_extensions_api.py -v\n\n# Run specific test class\npytest tests/api/test_extensions_api.py::TestCreateExtensions -v\n\n# Run specific test\npytest tests/api/test_extensions_api.py::TestCreateExtensions::test_create_with_valid_data -v\n```\n\n### With Schema Validation\n\n```bash\n# Enable schema validation in container\ndocker exec mikopbx_container sh -c 'export SCHEMA_VALIDATION_STRICT=1'\n\n# Run tests\npytest tests/api/test_extensions_api.py -v\n```\n\n### Test Markers\n\n```bash\n# Run only CRUD tests\npytest tests/api/ -m crud -v\n\n# Skip slow tests\npytest tests/api/ -m \"not slow\" -v\n\n# Run smoke tests\npytest tests/api/ -m smoke -v\n```\n\n## Important Notes\n\n### MikoPBX-Specific Considerations\n\n- **Authentication**: All tests need Bearer token from `/auth/login`\n- **HTTPS**: Use `verify=False` for self-signed certificates\n- **Base URL**: Default is `https://mikopbx-php83.localhost:8445`\n- **Schema validation**: Only active when `SCHEMA_VALIDATION_STRICT=1` in container\n- **Container restart**: Changes to PHP code require container restart\n- **Test isolation**: Each test should be independent and idempotent\n\n### Best Practices\n\n1. ✅ **Analyze DataStructure first** - Don't guess parameter structures\n2. ✅ **Include schema validation tests** - Only work with SCHEMA_VALIDATION_STRICT=1\n3. ✅ **Test success and failure cases** - Negative tests are critical\n4. ✅ **Use fixtures for auth** - Avoid code duplication\n5. ✅ **Clean up after tests** - Delete created resources in teardown\n6. ✅ **Document expected behavior** - Each test should state what it validates\n7. ✅ **Use descriptive test names** - Clear indication of what's being tested\n8. ✅ **One assertion per test** - Or group related assertions\n\n## Additional Resources\n\n### Templates\n\nComplete test templates for copy-paste usage:\n\n- **[test-template.py](templates/test-template.py)** - Complete pytest template with all test classes\n- **[crud-tests.py](templates/crud-tests.py)** - Reusable CRUD operation patterns\n- **[edge-cases.py](templates/edge-cases.py)** - Edge case and boundary test patterns\n\n### Reference Documentation\n\n- **[pytest-patterns.md](reference/pytest-patterns.md)** - Pytest patterns, fixtures, and best practices\n\n### Quick Reference\n\n**Test a new endpoint in 5 steps:**\n\n1. Find DataStructure.php\n2. Copy [test-template.py](templates/test-template.py)\n3. Replace `{ResourceName}` and `{resource-path}`\n4. Fill in payloads based on DataStructure\n5. Run `pytest tests/api/test_{resource}_api.py -v`\n\n**Need specific patterns?**\n\n- CRUD patterns → [crud-tests.py](templates/crud-tests.py)\n- Edge cases → [edge-cases.py](templates/edge-cases.py)\n- Pytest best practices → [pytest-patterns.md](reference/pytest-patterns.md)\n\n## Example Invocation\n\n**User**: \"Generate pytest tests for the Extensions API endpoint\"\n\n**Your response should:**\n\n1. Find `/src/PBXCoreREST/Lib/Extensions/DataStructure.php`\n2. Read and analyze parameter definitions\n3. Use [test-template.py](templates/test-template.py) as base\n4. Generate comprehensive test file with:\n - Valid test data from DataStructure\n - All CRUD operations\n - Edge cases for special characters, boundaries\n - Schema validation tests\n5. Save to `tests/api/test_extensions_api.py`\n6. Provide run instructions\n\n## Troubleshooting\n\n### Common Issues\n\n**Issue**: Test fails with \"Unauthorized\"\n**Solution**: Check that `auth_token` fixture is working and token is valid\n\n**Issue**: Schema validation tests don't run\n**Solution**: Ensure `SCHEMA_VALIDATION_STRICT=1` is set in container\n\n**Issue**: Tests are flaky\n**Solution**: Ensure test isolation - each test should create its own resources\n\n**Issue**: Container not accessible\n**Solution**: Check container is running: `docker ps | grep mikopbx`\n\n**Issue**: SSL certificate errors\n**Solution**: Ensure `verify=False` is set in requests\n\n### Debug Commands\n\n```bash\n# Check container is running\ndocker ps | grep mikopbx\n\n# Check environment variable\ndocker exec mikopbx_container env | grep SCHEMA_VALIDATION_STRICT\n\n# View API logs\ndocker exec mikopbx_container tail -f /storage/usbdisk1/mikopbx/log/php/error.log\n\n# Test API manually\ncurl -k https://mikopbx-php83.localhost:8445/pbxcore/api/v3/system/ping\n```\n---","attachment_filenames":["metadata.json"],"attachments":[{"filename":"metadata.json","content":"{\n \"id\": \"mikopbx-core-claude-skills-api-test-generator-skill-md\",\n \"name\": \"api-test-generator\",\n \"author\": \"mikopbx\",\n \"authorAvatar\": \"https://avatars.githubusercontent.com/u/58547382?v=4\",\n \"description\": \"\\u0413\\u0435\\u043d\\u0435\\u0440\\u0430\\u0446\\u0438\\u044f \\u043f\\u043e\\u043b\\u043d\\u044b\\u0445 Python pytest \\u0442\\u0435\\u0441\\u0442\\u043e\\u0432 \\u0434\\u043b\\u044f REST API \\u044d\\u043d\\u0434\\u043f\\u043e\\u0438\\u043d\\u0442\\u043e\\u0432 \\u0441 \\u0432\\u0430\\u043b\\u0438\\u0434\\u0430\\u0446\\u0438\\u0435\\u0439 \\u0441\\u0445\\u0435\\u043c\\u044b. \\u0418\\u0441\\u043f\\u043e\\u043b\\u044c\\u0437\\u043e\\u0432\\u0430\\u0442\\u044c \\u043f\\u0440\\u0438 \\u0441\\u043e\\u0437\\u0434\\u0430\\u043d\\u0438\\u0438 \\u0442\\u0435\\u0441\\u0442\\u043e\\u0432 \\u0434\\u043b\\u044f \\u043d\\u043e\\u0432\\u044b\\u0445 \\u044d\\u043d\\u0434\\u043f\\u043e\\u0438\\u043d\\u0442\\u043e\\u0432, \\u0434\\u043e\\u0431\\u0430\\u0432\\u043b\\u0435\\u043d\\u0438\\u0438 \\u043f\\u043e\\u043a\\u0440\\u044b\\u0442\\u0438\\u044f \\u0434\\u043b\\u044f CRUD \\u043e\\u043f\\u0435\\u0440\\u0430\\u0446\\u0438\\u0439 \\u0438\\u043b\\u0438 \\u0432\\u0430\\u043b\\u0438\\u0434\\u0430\\u0446\\u0438\\u0438 \\u0441\\u043e\\u043e\\u0442\\u0432\\u0435\\u0442\\u0441\\u0442\\u0432\\u0438\\u044f API \\u0441 OpenAPI \\u0441\\u0445\\u0435\\u043c\\u0430\\u043c\\u0438.\",\n \"githubUrl\": \"https://github.com/mikopbx/Core/tree/develop/.claude/skills/api-test-generator\",\n \"stars\": 489,\n \"forks\": 71,\n \"updatedAt\": 1764085725,\n \"hasMarketplace\": false,\n \"path\": \"SKILL.md\",\n \"branch\": \"main\"\n}","content_type":"application/json; charset=utf-8","language":"json","size":1456,"content_sha256":"f631224925381da9125d1068c0eee0d2c25bead8be097de7eb53891357b1d149"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"MikoPBX API Test Generating","type":"text"}]},{"type":"paragraph","content":[{"text":"Generate comprehensive Python pytest tests for MikoPBX REST API endpoints with full parameter coverage, schema validation, and edge case testing.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"What This Skill Does","type":"text"}]},{"type":"paragraph","content":[{"text":"Analyzes DataStructure.php files and generates complete pytest test suites including:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ CRUD operation tests (Create, Read, Update, Delete)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ Positive and negative test cases","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ Parameter validation tests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ Edge cases and boundary conditions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ Schema validation tests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ Proper fixtures and authentication","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ Detailed assertions with error messages","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use This Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"Use this skill when you need to:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create pytest tests for new REST API endpoints","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add comprehensive test coverage for existing endpoints","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate tests covering all parameter combinations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add schema validation tests for API responses","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create edge case and negative tests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ensure API compliance with OpenAPI specification","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Basic Usage","type":"text"}]},{"type":"paragraph","content":[{"text":"When the user requests test generation:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify the endpoint","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"API path (e.g., ","type":"text"},{"text":"/pbxcore/api/v3/extensions","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"HTTP methods (GET, POST, PUT, DELETE, PATCH)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Resource name (e.g., Extensions)","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Locate DataStructure.php","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"find /Users/nb/PhpstormProjects/mikopbx/Core/src/PBXCoreREST/Lib -name \"DataStructure.php\" | grep -i \"{resource}\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyze parameter definitions","type":"text","marks":[{"type":"strong"}]},{"text":" Extract from ","type":"text"},{"text":"DataStructure.php","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Required vs optional parameters","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Data types and validation rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Default values","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enum values","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pattern constraints (regex)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Min/max values","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate test file","type":"text","marks":[{"type":"strong"}]},{"text":" Use the complete template from ","type":"text"},{"text":"test-template.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/test-template.py","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Customize for endpoint","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Replace ","type":"text"},{"text":"{ResourceName}","type":"text","marks":[{"type":"code_inline"}]},{"text":" placeholders","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fill in actual payload structures","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Add specific field validations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Include enum and pattern validations","type":"text"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Test Structure","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"File Organization","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"tests/api/\n├── test_{resource}_api.py # Main test file\n└── conftest.py # Shared fixtures","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Test Class Structure","type":"text"}]},{"type":"paragraph","content":[{"text":"Each test file should have these test classes:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"class TestCreate{ResourceName}:\n \"\"\"Test POST endpoint for creating resources\"\"\"\n - test_create_with_valid_data()\n - test_create_missing_required_field()\n - test_create_with_invalid_type()\n\nclass TestGet{ResourceName}:\n \"\"\"Test GET endpoint for retrieving resources\"\"\"\n - test_get_all()\n - test_get_by_id()\n - test_get_nonexistent()\n\nclass TestUpdate{ResourceName}:\n \"\"\"Test PUT/PATCH endpoints for updating resources\"\"\"\n - test_update_with_valid_data()\n - test_patch_partial_update()\n\nclass TestDelete{ResourceName}:\n \"\"\"Test DELETE endpoint for removing resources\"\"\"\n - test_delete_existing()\n - test_delete_nonexistent()\n\nclass TestSchemaValidation{ResourceName}:\n \"\"\"Test response schema validation\"\"\"\n - test_response_matches_openapi_schema()\n\nclass TestEdgeCases{ResourceName}:\n \"\"\"Test edge cases and boundary conditions\"\"\"\n - test_special_characters_in_fields()\n - test_empty_string_values()\n - test_boundary_values()","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Standard Fixtures","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"@pytest.fixture\ndef auth_token():\n \"\"\"Get authentication token\"\"\"\n response = requests.post(\n f\"{BASE_URL}/pbxcore/api/v3/auth/login\",\n json={\"login\": \"admin\", \"password\": \"123456789MikoPBX#1\"},\n verify=False\n )\n return response.json()[\"data\"][\"access_token\"]\n\[email protected]\ndef headers(auth_token):\n \"\"\"Standard headers with authentication\"\"\"\n return {\n \"Authorization\": f\"Bearer {auth_token}\",\n \"Content-Type\": \"application/json\"\n }","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Test Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Create with Valid Data","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"def test_create_with_valid_data(self, headers):\n \"\"\"Test creating a resource with all valid required parameters\"\"\"\n payload = {\n # Based on DataStructure.php\n }\n\n response = requests.post(\n f\"{BASE_URL}{API_PATH}\",\n json=payload,\n headers=headers,\n verify=False\n )\n\n assert response.status_code == 200, f\"Expected 200, got {response.status_code}: {response.text}\"\n data = response.json()\n assert \"data\" in data\n assert \"id\" in data[\"data\"]\n\n # Validate returned values match input\n for key, value in payload.items():\n assert data[\"data\"][key] == value","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Validation Tests","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"def test_create_missing_required_field(self, headers):\n \"\"\"Test validation when required field is missing\"\"\"\n payload = {\n # Missing required field\n }\n\n response = requests.post(\n f\"{BASE_URL}{API_PATH}\",\n json=payload,\n headers=headers,\n verify=False\n )\n\n assert response.status_code == 400\n assert \"messages\" in response.json()","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Edge Cases","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"def test_special_characters_in_fields(self, headers):\n \"\"\"Test handling of special characters\"\"\"\n special_chars = \"Test \u003cscript>alert('xss')\u003c/script> & \\\"quotes\\\"\"\n payload = {\n \"string_field\": special_chars,\n }\n\n response = requests.post(...)\n assert response.status_code == 200\n assert response.json()[\"data\"][\"string_field\"] == special_chars","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"DataStructure Analysis","type":"text"}]},{"type":"paragraph","content":[{"text":"When analyzing DataStructure.php, extract these key elements:","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Parameter Structure","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"public static function getParameterDefinitions(): array\n{\n return [\n 'request' => [\n 'POST' => [\n 'parameter_name' => [\n 'type' => 'string', // Extract type\n 'description' => 'Description', // Extract description\n 'example' => 'value', // Use for test data\n 'required' => true, // Required vs optional\n 'default' => 'default_value', // Default value\n 'enum' => ['val1', 'val2'], // Valid enum values\n 'pattern' => '^[a-z]+

MikoPBX API Test Generating Generate comprehensive Python pytest tests for MikoPBX REST API endpoints with full parameter coverage, schema validation, and edge case testing. What This Skill Does Analyzes DataStructure.php files and generates complete pytest test suites including: - ✅ CRUD operation tests (Create, Read, Update, Delete) - ✅ Positive and negative test cases - ✅ Parameter validation tests - ✅ Edge cases and boundary conditions - ✅ Schema validation tests - ✅ Proper fixtures and authentication - ✅ Detailed assertions with error messages When to Use This Skill Use this skill when y…

, // Regex pattern\n 'minLength' => 1, // Min length\n 'maxLength' => 100, // Max length\n ],\n ],\n ],\n ];\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Use This Data To","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate valid payloads","type":"text","marks":[{"type":"strong"}]},{"text":" - Use ","type":"text"},{"text":"example","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"default","type":"text","marks":[{"type":"code_inline"}]},{"text":" values","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test required fields","type":"text","marks":[{"type":"strong"}]},{"text":" - Create tests omitting each required field","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test data types","type":"text","marks":[{"type":"strong"}]},{"text":" - Create tests with wrong types","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test enums","type":"text","marks":[{"type":"strong"}]},{"text":" - Create tests for each enum value and invalid values","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test patterns","type":"text","marks":[{"type":"strong"}]},{"text":" - Create tests for valid/invalid patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test boundaries","type":"text","marks":[{"type":"strong"}]},{"text":" - Create tests for min/max values","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Test Documentation Template","type":"text"}]},{"type":"paragraph","content":[{"text":"Add to the top of each test file:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"\"\"\"\nTests for {ResourceName} API endpoint\n\nAPI Endpoint: /pbxcore/api/v3/{resource-path}\nDataStructure: src/PBXCoreREST/Lib/{ResourceName}/DataStructure.php\n\nTest Coverage:\n- CRUD operations (Create, Read, Update, Delete)\n- Required vs optional parameters\n- Data type validations\n- Enum value validations\n- Pattern validations (regex)\n- Boundary conditions (min/max values)\n- Special characters and edge cases\n- Schema validation (when SCHEMA_VALIDATION_STRICT=1)\n\nRequirements:\n- pytest\n- requests\n- Docker container running with MikoPBX\n\nRun tests:\n pytest tests/api/test_{resource_name}.py -v\n\nRun with schema validation:\n # Ensure SCHEMA_VALIDATION_STRICT=1 is set in container\n pytest tests/api/test_{resource_name}.py -v\n\"\"\"","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"paragraph","content":[{"text":"Always generate:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Complete pytest file","type":"text","marks":[{"type":"strong"}]},{"text":" - Runnable without modifications","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Documentation block","type":"text","marks":[{"type":"strong"}]},{"text":" - Clear description at the top","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"All test classes","type":"text","marks":[{"type":"strong"}]},{"text":" - CRUD, schema validation, edge cases","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Proper fixtures","type":"text","marks":[{"type":"strong"}]},{"text":" - Authentication and headers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Clear assertions","type":"text","marks":[{"type":"strong"}]},{"text":" - With descriptive error messages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Comments","type":"text","marks":[{"type":"strong"}]},{"text":" - Explaining complex validations","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Running Tests","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Basic Execution","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Run all API tests\npytest tests/api/ -v\n\n# Run specific endpoint tests\npytest tests/api/test_extensions_api.py -v\n\n# Run specific test class\npytest tests/api/test_extensions_api.py::TestCreateExtensions -v\n\n# Run specific test\npytest tests/api/test_extensions_api.py::TestCreateExtensions::test_create_with_valid_data -v","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"With Schema Validation","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Enable schema validation in container\ndocker exec mikopbx_container sh -c 'export SCHEMA_VALIDATION_STRICT=1'\n\n# Run tests\npytest tests/api/test_extensions_api.py -v","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Test Markers","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Run only CRUD tests\npytest tests/api/ -m crud -v\n\n# Skip slow tests\npytest tests/api/ -m \"not slow\" -v\n\n# Run smoke tests\npytest tests/api/ -m smoke -v","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Important Notes","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"MikoPBX-Specific Considerations","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authentication","type":"text","marks":[{"type":"strong"}]},{"text":": All tests need Bearer token from ","type":"text"},{"text":"/auth/login","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"HTTPS","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"verify=False","type":"text","marks":[{"type":"code_inline"}]},{"text":" for self-signed certificates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Base URL","type":"text","marks":[{"type":"strong"}]},{"text":": Default is ","type":"text"},{"text":"https://mikopbx-php83.localhost:8445","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Schema validation","type":"text","marks":[{"type":"strong"}]},{"text":": Only active when ","type":"text"},{"text":"SCHEMA_VALIDATION_STRICT=1","type":"text","marks":[{"type":"code_inline"}]},{"text":" in container","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Container restart","type":"text","marks":[{"type":"strong"}]},{"text":": Changes to PHP code require container restart","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test isolation","type":"text","marks":[{"type":"strong"}]},{"text":": Each test should be independent and idempotent","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Best Practices","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Analyze DataStructure first","type":"text","marks":[{"type":"strong"}]},{"text":" - Don't guess parameter structures","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Include schema validation tests","type":"text","marks":[{"type":"strong"}]},{"text":" - Only work with SCHEMA_VALIDATION_STRICT=1","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Test success and failure cases","type":"text","marks":[{"type":"strong"}]},{"text":" - Negative tests are critical","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Use fixtures for auth","type":"text","marks":[{"type":"strong"}]},{"text":" - Avoid code duplication","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Clean up after tests","type":"text","marks":[{"type":"strong"}]},{"text":" - Delete created resources in teardown","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Document expected behavior","type":"text","marks":[{"type":"strong"}]},{"text":" - Each test should state what it validates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"Use descriptive test names","type":"text","marks":[{"type":"strong"}]},{"text":" - Clear indication of what's being tested","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"✅ ","type":"text"},{"text":"One assertion per test","type":"text","marks":[{"type":"strong"}]},{"text":" - Or group related assertions","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Additional Resources","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Templates","type":"text"}]},{"type":"paragraph","content":[{"text":"Complete test templates for copy-paste usage:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"test-template.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/test-template.py","title":null}},{"type":"strong"}]},{"text":" - Complete pytest template with all test classes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"crud-tests.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/crud-tests.py","title":null}},{"type":"strong"}]},{"text":" - Reusable CRUD operation patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"edge-cases.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/edge-cases.py","title":null}},{"type":"strong"}]},{"text":" - Edge case and boundary test patterns","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Reference Documentation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"pytest-patterns.md","type":"text","marks":[{"type":"link","attrs":{"href":"reference/pytest-patterns.md","title":null}},{"type":"strong"}]},{"text":" - Pytest patterns, fixtures, and best practices","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Quick Reference","type":"text"}]},{"type":"paragraph","content":[{"text":"Test a new endpoint in 5 steps:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Find DataStructure.php","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Copy ","type":"text"},{"text":"test-template.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/test-template.py","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Replace ","type":"text"},{"text":"{ResourceName}","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"{resource-path}","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fill in payloads based on DataStructure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"pytest tests/api/test_{resource}_api.py -v","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Need specific patterns?","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CRUD patterns → ","type":"text"},{"text":"crud-tests.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/crud-tests.py","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Edge cases → ","type":"text"},{"text":"edge-cases.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/edge-cases.py","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pytest best practices → ","type":"text"},{"text":"pytest-patterns.md","type":"text","marks":[{"type":"link","attrs":{"href":"reference/pytest-patterns.md","title":null}}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Example Invocation","type":"text"}]},{"type":"paragraph","content":[{"text":"User","type":"text","marks":[{"type":"strong"}]},{"text":": \"Generate pytest tests for the Extensions API endpoint\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Your response should:","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Find ","type":"text"},{"text":"/src/PBXCoreREST/Lib/Extensions/DataStructure.php","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read and analyze parameter definitions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"test-template.py","type":"text","marks":[{"type":"link","attrs":{"href":"templates/test-template.py","title":null}}]},{"text":" as base","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generate comprehensive test file with:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Valid test data from DataStructure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"All CRUD operations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Edge cases for special characters, boundaries","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Schema validation tests","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Save to ","type":"text"},{"text":"tests/api/test_extensions_api.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provide run instructions","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Troubleshooting","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Common Issues","type":"text"}]},{"type":"paragraph","content":[{"text":"Issue","type":"text","marks":[{"type":"strong"}]},{"text":": Test fails with \"Unauthorized\" ","type":"text"},{"text":"Solution","type":"text","marks":[{"type":"strong"}]},{"text":": Check that ","type":"text"},{"text":"auth_token","type":"text","marks":[{"type":"code_inline"}]},{"text":" fixture is working and token is valid","type":"text"}]},{"type":"paragraph","content":[{"text":"Issue","type":"text","marks":[{"type":"strong"}]},{"text":": Schema validation tests don't run ","type":"text"},{"text":"Solution","type":"text","marks":[{"type":"strong"}]},{"text":": Ensure ","type":"text"},{"text":"SCHEMA_VALIDATION_STRICT=1","type":"text","marks":[{"type":"code_inline"}]},{"text":" is set in container","type":"text"}]},{"type":"paragraph","content":[{"text":"Issue","type":"text","marks":[{"type":"strong"}]},{"text":": Tests are flaky ","type":"text"},{"text":"Solution","type":"text","marks":[{"type":"strong"}]},{"text":": Ensure test isolation - each test should create its own resources","type":"text"}]},{"type":"paragraph","content":[{"text":"Issue","type":"text","marks":[{"type":"strong"}]},{"text":": Container not accessible ","type":"text"},{"text":"Solution","type":"text","marks":[{"type":"strong"}]},{"text":": Check container is running: ","type":"text"},{"text":"docker ps | grep mikopbx","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Issue","type":"text","marks":[{"type":"strong"}]},{"text":": SSL certificate errors ","type":"text"},{"text":"Solution","type":"text","marks":[{"type":"strong"}]},{"text":": Ensure ","type":"text"},{"text":"verify=False","type":"text","marks":[{"type":"code_inline"}]},{"text":" is set in requests","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Debug Commands","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Check container is running\ndocker ps | grep mikopbx\n\n# Check environment variable\ndocker exec mikopbx_container env | grep SCHEMA_VALIDATION_STRICT\n\n# View API logs\ndocker exec mikopbx_container tail -f /storage/usbdisk1/mikopbx/log/php/error.log\n\n# Test API manually\ncurl -k https://mikopbx-php83.localhost:8445/pbxcore/api/v3/system/ping","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"api-test-generator","author":"@skillopedia","source":{"stars":231,"repo_name":"ordinary-claude-skills","origin_url":"https://github.com/microck/ordinary-claude-skills/blob/HEAD/skills_all/api-test-generator/SKILL.md","repo_owner":"microck","body_sha256":"1d4bfdacd47b4b7fedb93eb9e187ef44289c54e9df6f65f86d0003eb519835e7","cluster_key":"c8dbe0a1c24cdd9ddd7c4600e1517591b7e5610aa0f2d34fc950af1aaff42a40","clean_bundle":{"format":"clean-skill-bundle-v1","source":"microck/ordinary-claude-skills/skills_all/api-test-generator/SKILL.md","attachments":[{"id":"8a5e25d5-b052-5ac1-b0b7-e37246bfb71b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8a5e25d5-b052-5ac1-b0b7-e37246bfb71b/attachment.json","path":"metadata.json","size":1456,"sha256":"f631224925381da9125d1068c0eee0d2c25bead8be097de7eb53891357b1d149","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"23461235595566616609c08da0f96ed301efc613507869101f3640ca0e43d92c","attachment_count":1,"text_attachments":1,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":2,"skill_md_path":"skills_all/api-test-generator/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"testing-qa","category_label":"Testing"},"exact_dupes_collapsed_into_this":1},"version":"v1","category":"testing-qa","import_tag":"clean-skills-v1","description":"Генерация полных Python pytest тестов для REST API эндпоинтов с валидацией схемы. Использовать при создании тестов для новых эндпоинтов, добавлении покрытия для CRUD операций или валидации соответствия API с OpenAPI схемами.","allowed-tools":"Bash, Read, Grep, Glob"}},"renderedAt":1782979478001}

MikoPBX API Test Generating Generate comprehensive Python pytest tests for MikoPBX REST API endpoints with full parameter coverage, schema validation, and edge case testing. What This Skill Does Analyzes DataStructure.php files and generates complete pytest test suites including: - ✅ CRUD operation tests (Create, Read, Update, Delete) - ✅ Positive and negative test cases - ✅ Parameter validation tests - ✅ Edge cases and boundary conditions - ✅ Schema validation tests - ✅ Proper fixtures and authentication - ✅ Detailed assertions with error messages When to Use This Skill Use this skill when y…