Initial commit
This commit is contained in:
8
skills/contract-test-validator/assets/README.md
Normal file
8
skills/contract-test-validator/assets/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Assets
|
||||
|
||||
Bundled resources for contract-test-validator skill
|
||||
|
||||
- [ ] pact_contract_template.json: A template for creating Pact consumer contracts.
|
||||
- [ ] openapi_example.yaml: An example OpenAPI specification file.
|
||||
- [ ] report_template.html: A template for generating HTML reports of contract validation results.
|
||||
- [ ] config_template.yaml: A configuration template for setting up the contract testing environment.
|
||||
80
skills/contract-test-validator/assets/config_template.yaml
Normal file
80
skills/contract-test-validator/assets/config_template.yaml
Normal file
@@ -0,0 +1,80 @@
|
||||
# Configuration for the Contract Test Validator plugin.
|
||||
|
||||
# General settings
|
||||
general:
|
||||
# Enable or disable the plugin
|
||||
enabled: true
|
||||
# Log level (debug, info, warning, error, critical)
|
||||
log_level: info
|
||||
# Directory to store temporary files and reports.
|
||||
temp_dir: ./tmp/contract_tests # REPLACE_ME: Choose a suitable temporary directory
|
||||
# Fail fast. Stop on first error?
|
||||
fail_fast: false
|
||||
|
||||
# Pact settings
|
||||
pact:
|
||||
# Enable Pact contract testing
|
||||
enabled: true
|
||||
# Directory to store Pact files
|
||||
pact_dir: ./pacts # REPLACE_ME: Choose a directory for pact files
|
||||
# URL of the Pact Broker (optional)
|
||||
broker_url: YOUR_VALUE_HERE # e.g., https://pact-broker.example.com
|
||||
# Username for Pact Broker authentication (optional)
|
||||
broker_username: YOUR_VALUE_HERE
|
||||
# Password for Pact Broker authentication (optional)
|
||||
broker_password: YOUR_VALUE_HERE
|
||||
# Publish verification results to the Pact Broker
|
||||
publish_verification_results: false
|
||||
# Consumer version tag to use when publishing to the broker
|
||||
consumer_version_tag: main # REPLACE_ME: Specify the consumer version tag
|
||||
# Provider version tag to use when verifying from the broker
|
||||
provider_version_tag: main # REPLACE_ME: Specify the provider version tag
|
||||
|
||||
# OpenAPI validation settings
|
||||
openapi:
|
||||
# Enable OpenAPI validation
|
||||
enabled: true
|
||||
# Directory containing OpenAPI specifications
|
||||
spec_dir: ./openapi_specs # REPLACE_ME: Choose a directory for OpenAPI specs
|
||||
# Base URL to use for validation
|
||||
base_url: http://localhost:8080 # REPLACE_ME: The base URL of your API
|
||||
|
||||
# Breaking change detection settings
|
||||
breaking_change:
|
||||
# Enable breaking change detection
|
||||
enabled: true
|
||||
# Previous API definition file (e.g., OpenAPI spec)
|
||||
previous_api_definition: ./openapi_specs/previous.yaml # REPLACE_ME: Path to previous API definition
|
||||
# Current API definition file (e.g., OpenAPI spec)
|
||||
current_api_definition: ./openapi_specs/current.yaml # REPLACE_ME: Path to current API definition
|
||||
# Report format (text, json)
|
||||
report_format: text
|
||||
# Output file for breaking change report
|
||||
report_file: ./reports/breaking_changes.txt # REPLACE_ME: Choose a location for report
|
||||
|
||||
# Custom scripts (e.g., for setup and teardown)
|
||||
scripts:
|
||||
# Script to run before contract tests
|
||||
before_all: ./scripts/before_all.sh # REPLACE_ME: Path to setup script (optional)
|
||||
# Script to run after contract tests
|
||||
after_all: ./scripts/after_all.sh # REPLACE_ME: Path to teardown script (optional)
|
||||
|
||||
# Notification settings (e.g., Slack, email)
|
||||
notifications:
|
||||
# Enable notifications
|
||||
enabled: false
|
||||
# Type of notification (slack, email)
|
||||
type: slack # or email
|
||||
# Slack webhook URL (if using Slack notifications)
|
||||
slack_webhook_url: YOUR_VALUE_HERE # REPLACE_ME: Your Slack webhook URL
|
||||
# Email configuration (if using email notifications)
|
||||
email:
|
||||
sender: YOUR_VALUE_HERE # REPLACE_ME: Sender email address
|
||||
recipients: # REPLACE_ME: List of recipient email addresses
|
||||
- recipient1@example.com
|
||||
- recipient2@example.com
|
||||
smtp_server: YOUR_VALUE_HERE # REPLACE_ME: SMTP server address
|
||||
smtp_port: 587
|
||||
smtp_username: YOUR_VALUE_HERE # REPLACE_ME: SMTP username
|
||||
smtp_password: YOUR_VALUE_HERE # REPLACE_ME: SMTP password
|
||||
use_tls: true
|
||||
237
skills/contract-test-validator/assets/openapi_example.yaml
Normal file
237
skills/contract-test-validator/assets/openapi_example.yaml
Normal file
@@ -0,0 +1,237 @@
|
||||
# OpenAPI Specification Example for Contract Test Validator Plugin
|
||||
# This file defines the structure of an example API for testing purposes.
|
||||
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Example API for Contract Testing
|
||||
version: 1.0.0
|
||||
description: A simple API to demonstrate contract testing with Pact and OpenAPI validation.
|
||||
contact:
|
||||
name: REPLACE_ME - Your Name
|
||||
email: REPLACE_ME - your.email@example.com
|
||||
|
||||
servers:
|
||||
- url: https://api.example.com/v1
|
||||
description: Production server
|
||||
|
||||
paths:
|
||||
/users:
|
||||
get:
|
||||
summary: Get all users
|
||||
description: Retrieves a list of all users.
|
||||
operationId: getUsers
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
'500':
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
post:
|
||||
summary: Create a new user
|
||||
description: Creates a new user with the provided information.
|
||||
operationId: createUser
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateUserRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: User created successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
'400':
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'500':
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/users/{userId}:
|
||||
get:
|
||||
summary: Get user by ID
|
||||
description: Retrieves a specific user by their ID.
|
||||
operationId: getUserById
|
||||
parameters:
|
||||
- in: path
|
||||
name: userId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
description: The ID of the user to retrieve
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
'404':
|
||||
description: User not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'500':
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
put:
|
||||
summary: Update user by ID
|
||||
description: Updates a specific user by their ID.
|
||||
operationId: updateUserById
|
||||
parameters:
|
||||
- in: path
|
||||
name: userId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
description: The ID of the user to update
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateUserRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
'400':
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
description: User not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'500':
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
delete:
|
||||
summary: Delete user by ID
|
||||
description: Deletes a specific user by their ID.
|
||||
operationId: deleteUserById
|
||||
parameters:
|
||||
- in: path
|
||||
name: userId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
description: The ID of the user to delete
|
||||
responses:
|
||||
'204':
|
||||
description: User deleted successfully
|
||||
'404':
|
||||
description: User not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'500':
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: The user ID.
|
||||
name:
|
||||
type: string
|
||||
description: The user's name.
|
||||
email:
|
||||
type: string
|
||||
format: email
|
||||
description: The user's email address.
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The date and time the user was created.
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- email
|
||||
|
||||
CreateUserRequest:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The user's name.
|
||||
email:
|
||||
type: string
|
||||
format: email
|
||||
description: The user's email address.
|
||||
required:
|
||||
- name
|
||||
- email
|
||||
|
||||
UpdateUserRequest:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The user's name.
|
||||
email:
|
||||
type: string
|
||||
format: email
|
||||
description: The user's email address.
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
description: The error code.
|
||||
message:
|
||||
type: string
|
||||
description: The error message.
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth: # arbitrary name for the security scheme
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT # optional, for documentation purposes only
|
||||
|
||||
security:
|
||||
- bearerAuth: [] # applies the "bearerAuth" security scheme to all operations
|
||||
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"_comment": "Pact Consumer Contract Template",
|
||||
"consumer": {
|
||||
"name": "MyConsumer"
|
||||
},
|
||||
"provider": {
|
||||
"name": "MyProvider"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"_comment": "Example Interaction - GET request",
|
||||
"description": "a request to get a product",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"path": "/products/123",
|
||||
"headers": {
|
||||
"Accept": "application/json"
|
||||
},
|
||||
"_comment": "Optional: Query parameters"
|
||||
"query": ""
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json; charset=utf-8"
|
||||
},
|
||||
"body": {
|
||||
"id": 123,
|
||||
"name": "Example Product",
|
||||
"description": "A sample product for testing purposes",
|
||||
"price": 25.99,
|
||||
"inStock": true,
|
||||
"_comment": "Optional: Matchers for flexible validation"
|
||||
"_matchers": {
|
||||
"$.id": {
|
||||
"match": "type"
|
||||
},
|
||||
"$.price": {
|
||||
"match": "decimal"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "Product 123 exists",
|
||||
"_comment": "Optional: Define state setup for provider"
|
||||
"params": {
|
||||
"productId": 123
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"_comment": "Example Interaction - POST request",
|
||||
"description": "a request to create a new product",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"path": "/products",
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"body": {
|
||||
"name": "New Product",
|
||||
"description": "A new product to be created",
|
||||
"price": 10.00
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"status": 201,
|
||||
"headers": {
|
||||
"Content-Type": "application/json; charset=utf-8"
|
||||
},
|
||||
"body": {
|
||||
"id": 456,
|
||||
"name": "New Product",
|
||||
"description": "A new product to be created",
|
||||
"price": 10.00
|
||||
}
|
||||
},
|
||||
"providerStates": [
|
||||
{
|
||||
"name": "The system is in a valid state to create products"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"pactSpecification": {
|
||||
"version": "3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
161
skills/contract-test-validator/assets/report_template.html
Normal file
161
skills/contract-test-validator/assets/report_template.html
Normal file
@@ -0,0 +1,161 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Contract Validation Report</title>
|
||||
<style>
|
||||
/* Inline CSS for styling */
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background-color: #f4f4f4;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.report-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.section h2 {
|
||||
color: #007bff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.section p {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-success {
|
||||
background-color: #28a745; /* Green */
|
||||
}
|
||||
|
||||
.status-failure {
|
||||
background-color: #dc3545; /* Red */
|
||||
}
|
||||
|
||||
.status-warning {
|
||||
background-color: #ffc107; /* Yellow */
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.status-unknown {
|
||||
background-color: #6c757d; /* Gray */
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f2f2f2;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f8f8f8;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 600px) {
|
||||
.report-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 6px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="report-container">
|
||||
<h1>Contract Validation Report</h1>
|
||||
|
||||
<!-- Summary Section -->
|
||||
<div class="section">
|
||||
<h2>Summary</h2>
|
||||
<p>Report generated on: {{report_date}}</p>
|
||||
<p>Total tests: {{total_tests}}</p>
|
||||
<p>Passed: <span class="status-indicator status-success">{{passed_tests}}</span></p>
|
||||
<p>Failed: <span class="status-indicator status-failure">{{failed_tests}}</span></p>
|
||||
<p>Warnings: <span class="status-indicator status-warning">{{warning_tests}}</span></p>
|
||||
</div>
|
||||
|
||||
<!-- Pact Verification Results -->
|
||||
<div class="section">
|
||||
<h2>Pact Verification Results</h2>
|
||||
{{pact_results}}
|
||||
</div>
|
||||
|
||||
<!-- OpenAPI Validation Results -->
|
||||
<div class="section">
|
||||
<h2>OpenAPI Validation Results</h2>
|
||||
{{openapi_results}}
|
||||
</div>
|
||||
|
||||
<!-- Breaking Change Detection Results -->
|
||||
<div class="section">
|
||||
<h2>Breaking Change Detection Results</h2>
|
||||
{{breaking_change_results}}
|
||||
</div>
|
||||
|
||||
<!-- Raw Output Section -->
|
||||
<div class="section">
|
||||
<h2>Raw Output</h2>
|
||||
<pre>{{raw_output}}</pre>
|
||||
</div>
|
||||
|
||||
<!-- Additional Notes Section -->
|
||||
<div class="section">
|
||||
<h2>Additional Notes</h2>
|
||||
<p>{{additional_notes}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user