diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f5567f02189..b085c44ace9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -83,3 +83,8 @@ src/negative_test/popxf-* @peterstangl @alekssmolkovic @kenmimasu src/schemas/json/kya.json @wp-lkl src/test/kya/ @wp-lkl src/negative_test/kya/ @wp-lkl + +# Managed by Specmatic team: +src/schemas/json/specmatic.json @joelrosario @nashjain +src/test/specmatic/ @joelrosario @nashjain +src/negative_test/specmatic/ @joelrosario @nashjain diff --git a/src/negative_test/specmatic/v3-components-additional-properties.json b/src/negative_test/specmatic/v3-components-additional-properties.json new file mode 100644 index 00000000000..c3d6b40c758 --- /dev/null +++ b/src/negative_test/specmatic/v3-components-additional-properties.json @@ -0,0 +1,6 @@ +{ + "components": { + "unknownSection": {} + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-dependency-service-ref-and-definitions-together.json b/src/negative_test/specmatic/v3-dependency-service-ref-and-definitions-together.json new file mode 100644 index 00000000000..a6c8d0cdbc5 --- /dev/null +++ b/src/negative_test/specmatic/v3-dependency-service-ref-and-definitions-together.json @@ -0,0 +1,13 @@ +{ + "dependencies": { + "services": [ + { + "service": { + "$ref": "#/components/services/userApiService", + "definitions": [] + } + } + ] + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-examples-additional-properties.json b/src/negative_test/specmatic/v3-examples-additional-properties.json new file mode 100644 index 00000000000..a8d5e3b04b5 --- /dev/null +++ b/src/negative_test/specmatic/v3-examples-additional-properties.json @@ -0,0 +1,10 @@ +{ + "components": { + "examples": { + "invalidExamplesSection": { + "directories": "./examples" + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-examples-wrong-type.json b/src/negative_test/specmatic/v3-examples-wrong-type.json new file mode 100644 index 00000000000..bc739c0ebbf --- /dev/null +++ b/src/negative_test/specmatic/v3-examples-wrong-type.json @@ -0,0 +1,8 @@ +{ + "components": { + "examples": { + "testExamples": "not-an-array" + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-global-settings-additional-properties.json b/src/negative_test/specmatic/v3-global-settings-additional-properties.json new file mode 100644 index 00000000000..1f29e3d5442 --- /dev/null +++ b/src/negative_test/specmatic/v3-global-settings-additional-properties.json @@ -0,0 +1,10 @@ +{ + "specmatic": { + "settings": { + "general": { + "unsupportedSetting": true + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-global-settings-wrong-type.json b/src/negative_test/specmatic/v3-global-settings-wrong-type.json new file mode 100644 index 00000000000..52aaae010ed --- /dev/null +++ b/src/negative_test/specmatic/v3-global-settings-wrong-type.json @@ -0,0 +1,10 @@ +{ + "specmatic": { + "settings": { + "general": { + "prettyPrint": 1 + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-proxy-missing-target.json b/src/negative_test/specmatic/v3-proxy-missing-target.json new file mode 100644 index 00000000000..de93a8c7674 --- /dev/null +++ b/src/negative_test/specmatic/v3-proxy-missing-target.json @@ -0,0 +1,10 @@ +{ + "proxies": [ + { + "proxy": { + "baseUrl": "http://localhost:9000" + } + } + ], + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-root-additional-properties-contracts.json b/src/negative_test/specmatic/v3-root-additional-properties-contracts.json new file mode 100644 index 00000000000..38ef7b87f97 --- /dev/null +++ b/src/negative_test/specmatic/v3-root-additional-properties-contracts.json @@ -0,0 +1,4 @@ +{ + "contracts": [], + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-run-options-additional-properties.json b/src/negative_test/specmatic/v3-run-options-additional-properties.json new file mode 100644 index 00000000000..0e5eb5a9e2d --- /dev/null +++ b/src/negative_test/specmatic/v3-run-options-additional-properties.json @@ -0,0 +1,10 @@ +{ + "components": { + "runOptions": { + "orderApiService": { + "invalidProtocol": {} + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-run-options-openapi-missing-type.json b/src/negative_test/specmatic/v3-run-options-openapi-missing-type.json new file mode 100644 index 00000000000..25e4d8a5cd5 --- /dev/null +++ b/src/negative_test/specmatic/v3-run-options-openapi-missing-type.json @@ -0,0 +1,12 @@ +{ + "components": { + "runOptions": { + "orderApiService": { + "openapi": { + "baseUrl": "http://localhost:8080" + } + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-run-options-wrong-datatype.json b/src/negative_test/specmatic/v3-run-options-wrong-datatype.json new file mode 100644 index 00000000000..8aaed539237 --- /dev/null +++ b/src/negative_test/specmatic/v3-run-options-wrong-datatype.json @@ -0,0 +1,13 @@ +{ + "components": { + "runOptions": { + "orderApiService": { + "openapi": { + "baseUrl": 8080, + "type": "test" + } + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-source-mixed-git-and-filesystem.json b/src/negative_test/specmatic/v3-source-mixed-git-and-filesystem.json new file mode 100644 index 00000000000..f6fdce40be8 --- /dev/null +++ b/src/negative_test/specmatic/v3-source-mixed-git-and-filesystem.json @@ -0,0 +1,15 @@ +{ + "components": { + "sources": { + "specsRepo": { + "filesystem": { + "directory": "./local-specs" + }, + "git": { + "url": "https://github.com/example/specs-repo.git" + } + } + } + }, + "version": 3 +} diff --git a/src/negative_test/specmatic/v3-system-under-test-service-missing-ref-or-definitions.json b/src/negative_test/specmatic/v3-system-under-test-service-missing-ref-or-definitions.json new file mode 100644 index 00000000000..0cc159f5c34 --- /dev/null +++ b/src/negative_test/specmatic/v3-system-under-test-service-missing-ref-or-definitions.json @@ -0,0 +1,8 @@ +{ + "systemUnderTest": { + "service": { + "description": "Order API service" + } + }, + "version": 3 +} diff --git a/src/schemas/json/specmatic.json b/src/schemas/json/specmatic.json index 027d5e23874..25e50633778 100644 --- a/src/schemas/json/specmatic.json +++ b/src/schemas/json/specmatic.json @@ -4,97 +4,216 @@ "title": "Specmatic Configuration", "description": "Configuration file for Specmatic, a contract-driven testing tool\nhttps://specmatic.io/documentation/", "type": "object", - "required": ["version", "contracts"], - "additionalProperties": false, + "required": ["version"], "properties": { "version": { "type": "integer", - "enum": [2], - "description": "Configuration version for Specmatic" - }, - "contracts": { - "type": "array", - "description": "Array of contract configurations", - "items": { - "$ref": "#/definitions/ContractConfig" + "default": 2 + } + }, + "allOf": [ + { + "if": { + "properties": { + "version": { + "const": 3 + } + } + }, + "then": { + "$ref": "#/definitions/ConfigV3" + }, + "else": { + "$ref": "#/definitions/ConfigV2" } - }, - "auth": { - "$ref": "#/definitions/Auth", - "description": "Authentication configuration" - }, - "pipeline": { - "$ref": "#/definitions/Pipeline", - "description": "Pipeline configuration for Azure DevOps" - }, - "environments": { + } + ], + "definitions": { + "ConfigV3": { "type": "object", - "description": "Environment-specific configurations", - "additionalProperties": { - "$ref": "#/definitions/Environment" + "required": ["version"], + "additionalProperties": false, + "properties": { + "version": { + "type": "integer", + "enum": [3] + }, + "systemUnderTest": { + "$ref": "#/definitions/SystemUnderTestServiceDefinition" + }, + "dependencies": { + "$ref": "#/definitions/DependenciesDefinition" + }, + "proxies": { + "$ref": "#/definitions/ProxyDefinitionsArray" + }, + "mcp": { + "$ref": "#/definitions/McpDefinition" + }, + "specmatic": { + "$ref": "#/definitions/SpecmaticDefinition" + }, + "components": { + "type": "object", + "additionalProperties": false, + "properties": { + "sources": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/SourceSchema" + } + }, + "services": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/StaticServiceDefinition" + } + }, + "runOptions": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/RunOptions" + } + }, + "examples": { + "$ref": "#/definitions/ExamplesConfiguration" + }, + "dictionaries": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/DictionaryConfiguration" + } + }, + "adapters": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/AdapterConfiguration" + } + }, + "certificates": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/CertConfiguration" + } + }, + "settings": { + "type": "object", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/definitions/ConcreteSettings" + }, + { + "$ref": "#/definitions/ModeSpecificSettings" + } + ] + } + } + } + } } }, - "hooks": { + "ConfigV2": { "type": "object", - "description": "Custom hooks configuration", - "additionalProperties": { "type": "string" } - }, - "repository": { - "$ref": "#/definitions/RepositoryInfo", - "description": "Repository information" - }, - "report": { - "$ref": "#/definitions/ReportConfigurationDetails", - "description": "Report generation configuration" - }, - "security": { - "$ref": "#/definitions/SecurityConfiguration", - "description": "Security configuration for API testing" - }, - "test": { - "$ref": "#/definitions/TestConfiguration", - "description": "Test execution configuration" - }, - "stub": { - "$ref": "#/definitions/StubConfiguration", - "description": "Stub/mock server configuration" - }, - "virtualService": { - "$ref": "#/definitions/VirtualServiceConfiguration", - "description": "Virtual service configuration" - }, - "examples": { - "type": "array", - "description": "List of example file paths", - "items": { "type": "string" } - }, - "workflow": { - "$ref": "#/definitions/WorkflowConfiguration", - "description": "Workflow configuration for ID management" - }, - "ignoreInlineExamples": { - "type": ["boolean", "null"], - "description": "Whether to ignore inline examples in specifications" - }, - "additionalExampleParamsFilePath": { - "type": ["string", "null"], - "description": "Path to additional example parameters file" - }, - "attributeSelectionPattern": { - "$ref": "#/definitions/AttributeSelectionPattern", - "description": "Pattern for selecting attributes in responses" - }, - "allPatternsMandatory": { - "type": ["boolean", "null"], - "description": "Whether all patterns are mandatory" + "required": ["version", "contracts"], + "additionalProperties": false, + "properties": { + "version": { + "type": "integer", + "enum": [2], + "description": "Configuration version for Specmatic" + }, + "contracts": { + "type": "array", + "description": "Array of contract configurations", + "items": { + "$ref": "#/definitions/ContractConfig" + } + }, + "auth": { + "$ref": "#/definitions/Auth", + "description": "Authentication configuration" + }, + "pipeline": { + "$ref": "#/definitions/Pipeline", + "description": "Pipeline configuration for Azure DevOps" + }, + "environments": { + "type": "object", + "description": "Environment-specific configurations", + "additionalProperties": { + "$ref": "#/definitions/Environment" + } + }, + "hooks": { + "type": "object", + "description": "Custom hooks configuration", + "additionalProperties": { + "type": "string" + } + }, + "repository": { + "$ref": "#/definitions/RepositoryInfo", + "description": "Repository information" + }, + "report": { + "$ref": "#/definitions/ReportConfigurationDetails", + "description": "Report generation configuration" + }, + "security": { + "$ref": "#/definitions/SecurityConfiguration", + "description": "Security configuration for API testing" + }, + "test": { + "$ref": "#/definitions/TestConfiguration", + "description": "Test execution configuration" + }, + "stub": { + "$ref": "#/definitions/StubConfiguration", + "description": "Stub/mock server configuration" + }, + "virtualService": { + "$ref": "#/definitions/VirtualServiceConfiguration", + "description": "Virtual service configuration" + }, + "examples": { + "type": "array", + "description": "List of example file paths", + "items": { + "type": "string" + } + }, + "workflow": { + "$ref": "#/definitions/WorkflowConfiguration", + "description": "Workflow configuration for ID management" + }, + "ignoreInlineExamples": { + "type": ["boolean", "null"], + "description": "Whether to ignore inline examples in specifications" + }, + "additionalExampleParamsFilePath": { + "type": ["string", "null"], + "description": "Path to additional example parameters file" + }, + "attributeSelectionPattern": { + "$ref": "#/definitions/AttributeSelectionPattern", + "description": "Pattern for selecting attributes in responses" + }, + "allPatternsMandatory": { + "type": ["boolean", "null"], + "description": "Whether all patterns are mandatory" + }, + "defaultPatternValues": { + "type": "object", + "description": "Default values for patterns", + "additionalProperties": true + }, + "disable_telemetry": { + "type": ["boolean"], + "description": "Whether to disable telemetry data collection" + } + } }, - "defaultPatternValues": { - "type": "object", - "description": "Default values for patterns", - "additionalProperties": true - } - }, - "definitions": { "ContractConfig": { "type": "object", "title": "ContractConfig", @@ -133,92 +252,41 @@ "required": [] }, "provides": { - "type": "array", + "type": ["array", "null"], "description": "List of specs provided for testing. Each entry can be a string or an object.", "items": { - "oneOf": [ + "anyOf": [ { - "type": "string", - "description": "Path to a spec file." + "$ref": "#/definitions/StringValue" }, { - "type": "object", - "description": "Object describing provided specs and test configuration.", - "additionalProperties": false, - "properties": { - "specs": { - "type": "array", - "items": { "type": "string" }, - "description": "List of spec file paths." - }, - "baseUrl": { - "type": "string", - "description": "Test base URL." - }, - "host": { - "type": "string", - "description": "Host for the test base URL." - }, - "port": { - "type": "integer", - "description": "Port for the test base URL." - }, - "resiliencyTests": { - "type": "object", - "additionalProperties": false, - "description": "Resiliency test configuration.", - "properties": { - "enable": { - "type": "string", - "enum": ["all", "positiveOnly", "none"], - "description": "Resiliency test suite to enable." - } - }, - "required": [] - } - }, - "required": ["specs"] + "$ref": "#/definitions/ObjectValueFullUrl" + }, + { + "$ref": "#/definitions/ObjectValuePartialUrl" + }, + { + "$ref": "#/definitions/ConfigValue" } ] } }, "consumes": { - "type": "array", + "type": ["array", "null"], "description": "List of specs consumed for stubbing. Each entry can be a string or an object.", "items": { "oneOf": [ { - "type": "string", - "description": "Path to a spec file." + "$ref": "#/definitions/StringValue" }, { - "type": "object", - "additionalProperties": false, - "description": "Object describing consumed specs and stub configuration.", - "properties": { - "specs": { - "type": "array", - "items": { "type": "string" }, - "description": "List of spec file paths." - }, - "baseUrl": { - "type": "string", - "description": "Full base URL for the stub." - }, - "host": { - "type": "string", - "description": "Host for the stub base URL." - }, - "port": { - "type": "integer", - "description": "Port for the stub base URL." - }, - "basePath": { - "type": "string", - "description": "Base path for the stub base URL." - } - }, - "required": ["specs"] + "$ref": "#/definitions/ObjectValueFullUrl" + }, + { + "$ref": "#/definitions/ObjectValuePartialUrl" + }, + { + "$ref": "#/definitions/ConfigValue" } ] } @@ -273,12 +341,16 @@ "baseurls": { "type": ["object", "null"], "description": "Base URLs for different services", - "additionalProperties": { "type": "string" } + "additionalProperties": { + "type": "string" + } }, "variables": { "type": ["object", "null"], "description": "Environment variables", - "additionalProperties": { "type": "string" } + "additionalProperties": { + "type": "string" + } } } }, @@ -305,10 +377,14 @@ "formatters": { "type": ["array", "null"], "description": "List of report formatters", - "items": { "$ref": "#/definitions/ReportFormatterDetails" }, + "items": { + "$ref": "#/definitions/ReportFormatterDetails" + }, "deprecated": true }, - "types": { "$ref": "#/definitions/ReportTypes" } + "types": { + "$ref": "#/definitions/ReportTypes" + } } }, "ReportFormatterDetails": { @@ -358,7 +434,9 @@ "additionalProperties": false, "description": "Configuration for different report types", "properties": { - "APICoverage": { "$ref": "#/definitions/APICoverage" } + "APICoverage": { + "$ref": "#/definitions/APICoverage" + } } }, "APICoverage": { @@ -366,7 +444,9 @@ "additionalProperties": false, "description": "API coverage report configuration", "properties": { - "OpenAPI": { "$ref": "#/definitions/APICoverageConfiguration" } + "OpenAPI": { + "$ref": "#/definitions/APICoverageConfiguration" + } } }, "APICoverageConfiguration": { @@ -374,11 +454,15 @@ "additionalProperties": false, "description": "OpenAPI coverage configuration", "properties": { - "successCriteria": { "$ref": "#/definitions/SuccessCriteria" }, + "successCriteria": { + "$ref": "#/definitions/SuccessCriteria" + }, "excludedEndpoints": { "type": ["array", "null"], "description": "List of endpoints to exclude from coverage", - "items": { "type": "string" } + "items": { + "type": "string" + } } } }, @@ -406,7 +490,9 @@ "additionalProperties": false, "description": "Security configuration", "properties": { - "OpenAPI": { "$ref": "#/definitions/OpenAPISecurityConfiguration" } + "OpenAPI": { + "$ref": "#/definitions/OpenAPISecurityConfiguration" + } } }, "OpenAPISecurityConfiguration": { @@ -448,7 +534,9 @@ "description": "Test execution configuration", "additionalProperties": false, "properties": { - "resiliencyTests": { "$ref": "#/definitions/ResiliencyTestsConfig" }, + "resiliencyTests": { + "$ref": "#/definitions/ResiliencyTestsConfig" + }, "validateResponseValues": { "type": ["boolean", "null"], "description": "Whether to validate response values" @@ -522,7 +610,9 @@ "nonPatchableKeys": { "type": "array", "description": "List of keys that cannot be patched", - "items": { "type": "string" } + "items": { + "type": "string" + } } } }, @@ -563,13 +653,1813 @@ "default_fields": { "type": ["array", "null"], "description": "Default fields to include", - "items": { "type": "string" } + "items": { + "type": "string" + } }, "query_param_key": { "type": ["string", "null"], "description": "Query parameter key for field selection" } } + }, + "SpecsArray": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "StringValue": { + "type": "string", + "description": "A single spec path." + }, + "ObjectValueFullUrl": { + "type": "object", + "additionalProperties": false, + "required": ["baseUrl", "specs"], + "properties": { + "baseUrl": { + "type": "string" + }, + "specs": { + "$ref": "#/definitions/SpecsArray" + }, + "resiliencyTests": { + "$ref": "#/definitions/ResiliencyTestsConfig" + } + } + }, + "ObjectValuePartialUrl": { + "type": "object", + "required": ["specs"], + "anyOf": [ + { + "required": ["host"], + "properties": { + "host": { + "type": "string" + } + } + }, + { + "required": ["port"], + "properties": { + "port": { + "type": "integer" + } + } + } + ], + "properties": { + "specs": { + "$ref": "#/definitions/SpecsArray" + }, + "host": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "basePath": { + "type": "string" + }, + "resiliencyTests": { + "$ref": "#/definitions/ResiliencyTestsConfig" + } + } + }, + "ConfigValue": { + "type": "object", + "additionalProperties": false, + "required": ["specs", "specType", "config"], + "properties": { + "specs": { + "$ref": "#/definitions/SpecsArray" + }, + "specType": { + "type": "string" + }, + "config": { + "type": "object", + "additionalProperties": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/ConfigValueScalarOrComposite" + } + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ConfigValueScalarOrComposite" + } + } + ] + } + } + } + }, + "ConfigValueScalarOrComposite": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/ConfigValueScalarOrComposite" + } + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ConfigValueScalarOrComposite" + } + } + ] + }, + "SubstitutionExpression": { + "type": "string", + "pattern": "^\\$\\{[^}]+\\}$" + }, + "GuardedSubstitutionString": { + "type": "string", + "allOf": [ + { + "if": { + "pattern": "^\\$\\{" + }, + "then": { + "$ref": "#/definitions/SubstitutionExpression" + }, + "else": {} + } + ] + }, + "SubstitutableString": { + "type": "string" + }, + "SubstitutableStringArray": { + "type": "array", + "items": { + "$ref": "#/definitions/SubstitutableString" + } + }, + "SubstitutableInteger": { + "anyOf": [ + { + "type": "integer" + }, + { + "$ref": "#/definitions/GuardedSubstitutionString" + } + ] + }, + "SubstitutableFloat": { + "oneOf": [ + { + "type": "number" + }, + { + "$ref": "#/definitions/GuardedSubstitutionString" + } + ] + }, + "SubstitutableBoolean": { + "oneOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/GuardedSubstitutionString" + } + ] + }, + "SubstitutableStringOrArray": { + "oneOf": [ + { + "$ref": "#/definitions/SubstitutableString" + }, + { + "$ref": "#/definitions/SubstitutableStringArray" + } + ] + }, + "Reference": { + "type": "object", + "additionalProperties": true, + "properties": { + "$ref": { + "type": "string", + "format": "uri-reference" + } + } + }, + "DependenciesDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "services": { + "$ref": "#/definitions/MockRuntimeServiceDefinitionOrRefArray" + }, + "data": { + "$ref": "#/definitions/DataDefinition" + }, + "settings": { + "$ref": "#/definitions/MockSettingsOrRef" + } + } + }, + "MockRuntimeServiceDefinitionOrRefArray": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["service"], + "properties": { + "service": { + "$ref": "#/definitions/MockRuntimeServiceDefinition" + } + } + } + }, + "MockRuntimeServiceDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "$ref": { + "type": "string" + }, + "description": { + "type": "string" + }, + "definitions": { + "$ref": "#/definitions/SpecificationStaticDefinitionArray" + }, + "runOptions": { + "$ref": "#/definitions/MockRunOptionsOrRef" + }, + "data": { + "$ref": "#/definitions/DataDefinition" + }, + "settings": { + "$ref": "#/definitions/MockSettingsOrRef" + } + }, + "oneOf": [ + { + "required": ["$ref"], + "properties": { + "$ref": {} + }, + "not": { + "required": ["definitions"], + "properties": { + "definitions": {} + } + } + }, + { + "required": ["definitions"], + "properties": { + "definitions": {} + }, + "not": { + "required": ["$ref"], + "properties": { + "$ref": {} + } + } + } + ] + }, + "SystemUnderTestServiceDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "service": { + "$ref": "#/definitions/TestRuntimeServiceDefinition" + } + } + }, + "TestRuntimeServiceDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "$ref": { "type": "string" }, + "definitions": { + "$ref": "#/definitions/SpecificationStaticDefinitionArray" + }, + + "description": { "type": "string" }, + "runOptions": { "$ref": "#/definitions/TestRunOptionsOrRef" }, + "data": { "$ref": "#/definitions/DataDefinition" }, + "settings": { "$ref": "#/definitions/TestSettingsOrRef" } + }, + "oneOf": [ + { + "required": ["$ref"], + "properties": { + "$ref": {} + }, + "not": { + "required": ["definitions"], + "properties": { + "definitions": {} + } + } + }, + { + "required": ["definitions"], + "properties": { + "definitions": {} + }, + "not": { + "required": ["$ref"], + "properties": { + "$ref": {} + } + } + } + ] + }, + "DataDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "examples": { + "$ref": "#/definitions/ArrayExampleConfigurationOrRef" + }, + "dictionary": { + "$ref": "#/definitions/DictionaryConfigurationOrRef" + }, + "adapters": { + "$ref": "#/definitions/AdapterConfigurationOrRef" + } + } + }, + "ProxyDefinitionsArray": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["proxy"], + "properties": { + "proxy": { + "$ref": "#/definitions/ProxyDefinition" + } + } + } + }, + "ProxyDefinition": { + "type": "object", + "additionalProperties": false, + "required": ["target"], + "properties": { + "target": { + "$ref": "#/definitions/SubstitutableString" + }, + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "timeoutInMilliseconds": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "adapters": { + "$ref": "#/definitions/AdapterConfigurationOrRef" + }, + "mock": { + "$ref": "#/definitions/SubstitutableStringOrArray" + }, + "cert": { + "$ref": "#/definitions/CertConfigurationOrRef" + }, + "recordingsDirectory": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "McpDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "test": { + "$ref": "#/definitions/McpTestRunOptions" + } + } + }, + "McpTestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "transportKind": { + "anyOf": [ + { + "type": "string", + "enum": ["STREAMABLE_HTTP"] + }, + { + "$ref": "#/definitions/SubstitutableString" + } + ] + }, + "enableResiliencyTests": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "dictionaryFile": { + "$ref": "#/definitions/SubstitutableString" + }, + "bearerToken": { + "$ref": "#/definitions/SubstitutableString" + }, + "filterTools": { + "$ref": "#/definitions/SubstitutableStringArray" + }, + "skipTools": { + "$ref": "#/definitions/SubstitutableStringArray" + } + } + }, + "SpecmaticDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "license": { + "$ref": "#/definitions/LicenseDefinition" + }, + "governance": { + "type": "object", + "additionalProperties": false, + "properties": { + "report": { + "$ref": "#/definitions/ReportsDefinition" + }, + "successCriteria": { + "$ref": "#/definitions/SuccessCriteriaDefinition" + } + } + }, + "settings": { + "$ref": "#/definitions/ConcreteSettingsOrRef" + } + } + }, + "LicenseDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "path": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "ReportsDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "formats": { + "oneOf": [ + { + "type": "array", + "items": { + "type": "string", + "enum": ["html", "ctrf"] + } + }, + { + "$ref": "#/definitions/SubstitutableString" + } + ] + }, + "outputDirectory": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "SuccessCriteriaDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "minCoveragePercentage": { + "$ref": "#/definitions/SubstitutableFloat" + }, + "maxMissedOperationsInSpec": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "enforce": { + "$ref": "#/definitions/SubstitutableBoolean" + } + } + }, + "StaticServiceDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "definitions": { + "$ref": "#/definitions/SpecificationStaticDefinitionArray" + } + } + }, + "SpecificationStaticDefinitionArray": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["definition"], + "properties": { + "definition": { + "$ref": "#/definitions/SpecificationStaticDefinition" + } + } + } + }, + "SpecificationStaticDefinition": { + "type": "object", + "additionalProperties": false, + "required": ["source", "specs"], + "properties": { + "source": { + "$ref": "#/definitions/SourceSchemaOrRef" + }, + "specs": { + "type": "array", + "items": { + "$ref": "#/definitions/SpecificationSchema" + } + } + } + }, + "SpecificationSchema": { + "oneOf": [ + { + "$ref": "#/definitions/SpecificationPath" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "spec": { + "$ref": "#/definitions/SpecificationObject" + } + } + } + ] + }, + "SpecificationPath": { + "type": "string" + }, + "SpecificationObject": { + "type": "object", + "additionalProperties": false, + "required": ["path"], + "properties": { + "id": { + "type": "string" + }, + "path": { + "type": "string" + }, + "urlPathPrefix": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "SourceSchemaOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/SourceSchema" + } + }, + "SourceSchema": { + "oneOf": [ + { + "$ref": "#/definitions/GitSourceSchema" + }, + { + "$ref": "#/definitions/FileSystemSourceSchema" + } + ] + }, + "GitSourceSchema": { + "type": "object", + "additionalProperties": false, + "required": ["git"], + "properties": { + "git": { + "$ref": "#/definitions/GitSourceOptions" + } + } + }, + "GitSourceOptions": { + "type": "object", + "additionalProperties": false, + "required": ["url"], + "properties": { + "url": { + "$ref": "#/definitions/SubstitutableString" + }, + "branch": { + "$ref": "#/definitions/SubstitutableString" + }, + "matchBranch": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "auth": { + "$ref": "#/definitions/GitSourceAuthentication" + } + } + }, + "GitSourceAuthentication": { + "oneOf": [ + { + "$ref": "#/definitions/GitSourceBearerFileAuthentication" + }, + { + "$ref": "#/definitions/GitSourceBearerEnvAuthentication" + }, + { + "$ref": "#/definitions/GitSourcePersonalAccessTokenAuthentication" + } + ] + }, + "GitSourceBearerFileAuthentication": { + "type": "object", + "additionalProperties": false, + "required": ["bearerFile"], + "properties": { + "bearerFile": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "GitSourceBearerEnvAuthentication": { + "type": "object", + "additionalProperties": false, + "required": ["bearerEnvironmentVariable"], + "properties": { + "bearerEnvironmentVariable": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "GitSourcePersonalAccessTokenAuthentication": { + "type": "object", + "additionalProperties": false, + "required": ["personalAccessToken"], + "properties": { + "personalAccessToken": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "FileSystemSourceSchema": { + "type": "object", + "additionalProperties": false, + "required": ["filesystem"], + "properties": { + "filesystem": { + "$ref": "#/definitions/FileSystemSourceOptions" + } + } + }, + "FileSystemSourceOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "directory": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "RunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "openapi": { + "$ref": "#/definitions/OpenApiRunOptions" + }, + "wsdl": { + "$ref": "#/definitions/WsdlRunOptions" + }, + "asyncapi": { + "$ref": "#/definitions/AsyncApiRunOptions" + }, + "graphqlsdl": { + "$ref": "#/definitions/GraphQLSdlRunOptions" + }, + "protobuf": { + "$ref": "#/definitions/ProtobufRunOptions" + } + } + }, + "TestRunOptionsOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/TestRunOptions" + } + }, + "TestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "openapi": { + "$ref": "#/definitions/OpenApiTestRunOptions" + }, + "wsdl": { + "$ref": "#/definitions/WsdlTestRunOptions" + }, + "asyncapi": { + "$ref": "#/definitions/AsyncApiTestRunOptions" + }, + "graphqlsdl": { + "$ref": "#/definitions/GraphqlSdlTestRunOptions" + }, + "protobuf": { + "$ref": "#/definitions/ProtobufTestRunOptions" + } + } + }, + "MockRunOptionsOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/MockRunOptions" + } + }, + "MockRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "openapi": { + "$ref": "#/definitions/OpenApiMockRunOptions" + }, + "wsdl": { + "$ref": "#/definitions/WsdlMockRunOptions" + }, + "asyncapi": { + "$ref": "#/definitions/AsyncApiMockRunOptions" + }, + "graphqlsdl": { + "$ref": "#/definitions/GraphqlSdlMockRunOptions" + }, + "protobuf": { + "$ref": "#/definitions/ProtobufMockRunOptions" + } + } + }, + "OpenApiRunOptions": { + "type": "object", + "required": ["type"], + "if": { + "properties": { + "type": { + "const": "test" + } + } + }, + "then": { + "$ref": "#/definitions/OpenApiTestRunOptions" + }, + "else": { + "$ref": "#/definitions/OpenApiMockRunOptions" + } + }, + "AsyncApiRunOptions": { + "type": "object", + "required": ["type"], + "if": { + "properties": { + "type": { + "const": "test" + } + } + }, + "then": { + "$ref": "#/definitions/AsyncApiTestRunOptions" + }, + "else": { + "$ref": "#/definitions/AsyncApiMockRunOptions" + } + }, + "GraphQLSdlRunOptions": { + "type": "object", + "required": ["type"], + "if": { + "properties": { + "type": { + "const": "test" + } + } + }, + "then": { + "$ref": "#/definitions/GraphqlSdlTestRunOptions" + }, + "else": { + "$ref": "#/definitions/GraphqlSdlMockRunOptions" + } + }, + "ProtobufRunOptions": { + "type": "object", + "required": ["type"], + "if": { + "properties": { + "type": { + "const": "test" + } + } + }, + "then": { + "$ref": "#/definitions/ProtobufTestRunOptions" + }, + "else": { + "$ref": "#/definitions/ProtobufMockRunOptions" + } + }, + "WsdlRunOptions": { + "type": "object", + "required": ["type"], + "if": { + "properties": { + "type": { + "const": "test" + } + } + }, + "then": { + "$ref": "#/definitions/WsdlTestRunOptions" + }, + "else": { + "$ref": "#/definitions/WsdlMockRunOptions" + } + }, + "WsdlTestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "test" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "WsdlMockRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "mock" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "cert": { + "$ref": "#/definitions/CertConfigurationOrRef" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "AsyncApiTestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "test" + }, + "replyTimeout": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "subscriberReadinessWaitTimeout": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "servers": { + "type": "array", + "items": { + "$ref": "#/definitions/AsyncApiServerDefinition" + } + }, + "schemaRegistry": { + "$ref": "#/definitions/AsyncApiSchemaRegistry" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "AsyncApiServerDefinition": { + "type": "object", + "additionalProperties": false, + "required": ["host", "protocol"], + "properties": { + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "protocol": { + "$ref": "#/definitions/SubstitutableString" + }, + "adminCredentials": { + "$ref": "#/definitions/FreeFormObject" + }, + "client": { + "type": "object", + "additionalProperties": false, + "properties": { + "consumer": { + "$ref": "#/definitions/CertConfigurationOrRef" + }, + "producer": { + "$ref": "#/definitions/CertConfigurationOrRef" + } + } + } + } + }, + "AsyncApiMockRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "mock" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + }, + "servers": { + "type": "array", + "items": { + "$ref": "#/definitions/AsyncApiServerDefinition" + } + }, + "schemaRegistry": { + "$ref": "#/definitions/AsyncApiSchemaRegistry" + }, + "inMemoryBroker": { + "type": "object", + "additionalProperties": false, + "properties": { + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "logDir": { + "$ref": "#/definitions/SubstitutableString" + } + } + } + } + }, + "AsyncApiSchemaRegistry": { + "type": "object", + "additionalProperties": false, + "required": ["kind"], + "properties": { + "kind": { + "anyOf": [ + { + "type": "string", + "enum": ["CONFLUENT", "DEFAULT"] + }, + { + "$ref": "#/definitions/SubstitutableString" + } + ] + }, + "url": { + "$ref": "#/definitions/SubstitutableString" + }, + "username": { + "$ref": "#/definitions/SubstitutableString" + }, + "password": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "GraphqlSdlTestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "test" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "GraphqlSdlMockRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "mock" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "ProtobufTestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "test" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "importPaths": { + "$ref": "#/definitions/SubstitutableStringArray" + }, + "protocVersion": { + "$ref": "#/definitions/SubstitutableString" + }, + "requestTimeout": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "ProtobufMockRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "mock" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "importPaths": { + "$ref": "#/definitions/SubstitutableStringArray" + }, + "protocVersion": { + "$ref": "#/definitions/SubstitutableString" + }, + "specs": { + "$ref": "#/definitions/SpecificationRuntimeDefinitionArray" + } + } + }, + "OpenApiTestRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "test" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "filter": { + "$ref": "#/definitions/SubstitutableString" + }, + "workflow": { + "$ref": "#/definitions/WorkflowConfigurationV3" + }, + "swaggerUiBaseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "swaggerUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "actuatorUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "specs": { + "$ref": "#/definitions/OpenApiSpecificationRuntimeDefinitionArray" + } + } + }, + "OpenApiMockRunOptions": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "enum": ["mock", "stateful-mock"] + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "filter": { + "$ref": "#/definitions/SubstitutableString" + }, + "logMode": { + "anyOf": [ + { + "type": "string", + "enum": ["ALL", "REQUEST_RESPONSE"] + }, + { + "$ref": "#/definitions/SubstitutableString" + } + ] + }, + "logsDirPath": { + "$ref": "#/definitions/SubstitutableString" + }, + "cert": { + "$ref": "#/definitions/CertConfigurationOrRef" + }, + "specs": { + "$ref": "#/definitions/OpenApiSpecificationRuntimeDefinitionArray" + } + } + }, + "OpenApiSpecificationRuntimeDefinitionArray": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["spec"], + "properties": { + "spec": { + "$ref": "#/definitions/OpenApiSpecificationRuntimeDefinition" + } + } + } + }, + "SpecificationRuntimeDefinitionArray": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["spec"], + "properties": { + "spec": { + "$ref": "#/definitions/SpecificationRuntimeDefinition" + } + } + } + }, + "FreeFormObject": { + "type": "object", + "additionalProperties": {} + }, + "SpecificationRuntimeDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "overlayFilePath": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "OpenApiSpecificationRuntimeDefinition": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "host": { + "$ref": "#/definitions/SubstitutableString" + }, + "port": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "baseUrl": { + "$ref": "#/definitions/SubstitutableString" + }, + "overlayFilePath": { + "$ref": "#/definitions/SubstitutableString" + }, + "securitySchemes": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/SecuritySchemeConfigurationV3" + } + } + } + }, + "SecuritySchemeConfigurationV3": { + "type": "object", + "additionalProperties": false, + "required": ["type", "token"], + "properties": { + "type": { + "type": "string", + "enum": ["oauth2", "basicAuth", "bearer", "apiKey"] + }, + "token": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "WorkflowConfigurationV3": { + "type": "object", + "additionalProperties": false, + "properties": { + "ids": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "extract": { + "$ref": "#/definitions/SubstitutableString" + }, + "use": { + "$ref": "#/definitions/SubstitutableString" + } + } + } + } + } + }, + "ExamplesConfiguration": { + "type": "object", + "additionalProperties": false, + "properties": { + "testExamples": { + "type": "array", + "items": { + "$ref": "#/definitions/BaseExampleConfigurationOrRef" + } + }, + "mockExamples": { + "type": "array", + "items": { + "$ref": "#/definitions/BaseExampleConfigurationOrRef" + } + }, + "commonExamples": { + "$ref": "#/definitions/BaseExampleConfiguration" + } + } + }, + "ArrayExampleConfigurationOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/ArrayExampleConfiguration" + } + }, + "ArrayExampleConfiguration": { + "type": "array", + "items": { + "$ref": "#/definitions/BaseExampleConfigurationOrRef" + } + }, + "BaseExampleConfigurationOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/BaseExampleConfiguration" + } + }, + "BaseExampleConfiguration": { + "type": "object", + "additionalProperties": false, + "required": ["directories"], + "properties": { + "directories": { + "$ref": "#/definitions/SubstitutableStringArray" + } + } + }, + "DictionaryConfigurationOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/DictionaryConfiguration" + } + }, + "DictionaryConfiguration": { + "type": "object", + "additionalProperties": false, + "required": ["path"], + "properties": { + "path": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "AdapterConfigurationOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/AdapterConfiguration" + } + }, + "AdapterConfiguration": { + "type": "object", + "additionalProperties": false, + "properties": { + "pre_specmatic_request_processor": { + "$ref": "#/definitions/SubstitutableString" + }, + "post_specmatic_response_processor": { + "$ref": "#/definitions/SubstitutableString" + }, + "pre_specmatic_response_processor": { + "$ref": "#/definitions/SubstitutableString" + }, + "stub_load_contract": { + "$ref": "#/definitions/SubstitutableString" + }, + "test_load_contract": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "CertConfigurationOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/CertConfiguration" + } + }, + "CertConfiguration": { + "type": "object", + "additionalProperties": false, + "required": ["keyStore"], + "properties": { + "keyStore": { + "$ref": "#/definitions/KeyStoreConfiguration" + }, + "keyStorePassword": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "ConcreteSettingsOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/ConcreteSettings" + } + }, + "ModeSpecificSettings": { + "type": "object", + "anyOf": [ + { + "$ref": "#/definitions/TestSettings" + }, + { + "$ref": "#/definitions/MockSettings" + } + ] + }, + "ConcreteSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "general": { + "$ref": "#/definitions/GeneralSettings" + }, + "test": { + "$ref": "#/definitions/TestSettings" + }, + "mock": { + "$ref": "#/definitions/MockSettings" + }, + "proxy": { + "$ref": "#/definitions/ProxySettings" + }, + "backwardCompatibility": { + "$ref": "#/definitions/BackwardCompatibilitySettings" + } + } + }, + "KeyStoreConfiguration": { + "oneOf": [ + { + "$ref": "#/definitions/KeyStoreFileConfiguration" + }, + { + "$ref": "#/definitions/KeyStoreDirectoryConfiguration" + } + ] + }, + "KeyStoreFileConfiguration": { + "type": "object", + "additionalProperties": false, + "required": ["file"], + "properties": { + "file": { + "$ref": "#/definitions/SubstitutableString" + }, + "password": { + "$ref": "#/definitions/SubstitutableString" + }, + "alias": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "KeyStoreDirectoryConfiguration": { + "type": "object", + "additionalProperties": false, + "required": ["directory"], + "properties": { + "directory": { + "$ref": "#/definitions/SubstitutableString" + }, + "password": { + "$ref": "#/definitions/SubstitutableString" + }, + "alias": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "BackwardCompatibilitySettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "baseBranch": { + "$ref": "#/definitions/SubstitutableString" + }, + "targetPath": { + "$ref": "#/definitions/SubstitutableString" + }, + "repoDirectory": { + "$ref": "#/definitions/SubstitutableString" + }, + "strictMode": { + "$ref": "#/definitions/SubstitutableBoolean" + } + } + }, + "ProxySettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "recordRequests": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "ignoreHeaders": { + "$ref": "#/definitions/SubstitutableStringArray" + } + } + }, + "MockSettingsOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/MockSettings" + } + }, + "MockSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "generative": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "delayInMilliseconds": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "startTimeoutInMilliseconds": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "hotReload": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "strictMode": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "lenientMode": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "gracefulRestartTimeoutInMilliseconds": { + "$ref": "#/definitions/SubstitutableInteger" + } + } + }, + "TestSettingsOrRef": { + "if": { + "type": "object", + "required": ["$ref"], + "properties": { + "$ref": { + "type": "string" + } + } + }, + "then": { + "$ref": "#/definitions/Reference" + }, + "else": { + "$ref": "#/definitions/TestSettings" + } + }, + "TestSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "schemaResiliencyTests": { + "anyOf": [ + { + "type": "string", + "enum": ["all", "none", "positiveOnly"] + }, + { + "$ref": "#/definitions/SubstitutableString" + } + ] + }, + "timeoutInMilliseconds": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "strictMode": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "lenientMode": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "parallelism": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "maxTestRequestCombinations": { + "$ref": "#/definitions/SubstitutableInteger" + }, + "junitReportDir": { + "$ref": "#/definitions/SubstitutableString" + }, + "validateResponseValues": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "maxTestCount": { + "$ref": "#/definitions/SubstitutableInteger" + } + } + }, + "GeneralSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "disableTelemetry": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "ignoreInlineExamples": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "ignoreInlineExampleWarnings": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "prettyPrint": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "logging": { + "$ref": "#/definitions/LoggingSettings" + }, + "featureFlags": { + "$ref": "#/definitions/FeatureFlags" + }, + "specExamplesDirectoryTemplate": { + "$ref": "#/definitions/SubstitutableString" + }, + "sharedExamplesDirectoryTemplate": { + "$ref": "#/definitions/SubstitutableStringArray" + } + } + }, + "LoggingSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "level": { + "anyOf": [ + { + "type": "string", + "enum": ["DEBUG", "INFO"] + }, + { + "$ref": "#/definitions/SubstitutableString" + } + ] + }, + "text": { + "$ref": "#/definitions/LogOutputSettings" + }, + "json": { + "$ref": "#/definitions/LogOutputSettings" + } + } + }, + "LogOutputSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "directory": { + "$ref": "#/definitions/SubstitutableString" + }, + "console": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "logFilePrefix": { + "$ref": "#/definitions/SubstitutableString" + } + } + }, + "FeatureFlags": { + "type": "object", + "additionalProperties": false, + "properties": { + "fuzzyMatcherForPayloads": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "schemaExampleDefault": { + "$ref": "#/definitions/SubstitutableBoolean" + }, + "escapeSoapAction": { + "$ref": "#/definitions/SubstitutableBoolean" + } + } } } } diff --git a/src/test/specmatic/specmatic-uber-v3.json b/src/test/specmatic/specmatic-uber-v3.json new file mode 100644 index 00000000000..ef9987db9d6 --- /dev/null +++ b/src/test/specmatic/specmatic-uber-v3.json @@ -0,0 +1,432 @@ +{ + "components": { + "adapters": { + "apiServiceHooks": { + "post_specmatic_response_processor": "./hooks/encode_response_to_consumer.sh", + "pre_specmatic_request_processor": "./hooks/decode_request_from_consumer.sh", + "pre_specmatic_response_processor": "./hooks/decode_response_from_provider.sh" + }, + "productServiceHooks": { + "pre_specmatic_request_processor": "./hooks/decode_request_from_consumer.sh", + "pre_specmatic_response_processor": "./hooks/decode_response_from_provider.sh" + } + }, + "certificates": { + "serverCert": { + "keyStore": { + "alias": "specmatic_server", + "file": "./certs/proxy-keystore.jks", + "password": "changeit" + }, + "keyStorePassword": "changeit" + } + }, + "dictionaries": { + "globalDictionary": { + "path": "./dictionaries/global-dictionary.yaml" + }, + "productServiceDictionary": { + "path": "./stub-dictionary.json" + } + }, + "examples": { + "commonExamples": { + "directories": [ + "./common-examples-for-my-service", + "./common-examples-for-all-service" + ] + }, + "mockExamples": [ + { + "directories": ["./mock-examples", "./mock-data"] + }, + { + "$ref": "#/components/examples/commonExamples" + } + ], + "testExamples": [ + { + "directories": ["./test-examples", "./test-examples", "./test-data"] + }, + { + "$ref": "#/components/examples/commonExamples" + } + ] + }, + "runOptions": { + "orderApiService": { + "openapi": { + "actuatorUrl": "http://localhost:8080/actuator", + "baseUrl": "${ORDER_API_SERVICE_BASE_URL:http://localhost:8080}", + "specs": [ + { + "spec": { + "id": "orderAPIServiceSpec", + "overlayFilePath": "./overlays/order-service-overlay.yaml", + "securitySchemes": { + "apiKeyScheme": { + "token": "${API_KEY:default_API_key_value}", + "type": "apiKey" + }, + "basicScheme": { + "token": "${BASIC_AUTH_USER:default_user}:${BASIC_AUTH_PWD:default_pwd}", + "type": "basicAuth" + }, + "bearerScheme": { + "token": "${BEARER_TOKEN:default_bearer_token}", + "type": "bearer" + }, + "oauthScheme": { + "token": "${OAUTH2_TOKEN:default_token_value}", + "type": "oauth2" + } + } + } + }, + { + "spec": { + "id": "userAPIServiceSpec", + "overlayFilePath": "./overlays/user-service-overlay.yaml" + } + } + ], + "swaggerUrl": "http://localhost:8080/v3/api-docs", + "type": "test", + "workflow": { + "ids": { + "*": { + "use": "$.globalId" + }, + "createUser": { + "extract": "$.userId" + } + } + } + } + }, + "userApiService": { + "asyncapi": { + "inMemoryBroker": { + "host": "localhost", + "port": 9092 + }, + "servers": [ + { + "host": "localhost:9092", + "protocol": "kafka" + } + ], + "type": "mock" + }, + "openapi": { + "baseUrl": "${USER_API_SERVICE_BASE_URL:http://localhost:9000}", + "cert": { + "$ref": "#/components/certificates/serverCert" + }, + "filter": "PATH=\"/order\" && METHOD=\"POST\"", + "logMode": "REQUEST_RESPONSE", + "logsDirPath": "./vs-logs", + "specs": [ + { + "spec": { + "id": "userAPIServiceSpec", + "securitySchemes": { + "bearerScheme": { + "token": "${USER_API_BEARER_TOKEN:default_user_bearer_token}", + "type": "bearer" + } + } + } + } + ], + "type": "stateful-mock" + } + } + }, + "services": { + "orderApiService": { + "definitions": [ + { + "definition": { + "source": { + "$ref": "#/components/sources/specsRepo" + }, + "specs": [ + { + "spec": { + "id": "orderAPIServiceSpec", + "path": "api_specs/oas/order-api-oas.yaml", + "urlPathPrefix": "/v1/http/orders" + } + }, + { + "spec": { + "path": "api_specs/proto/order-api-grpc.proto" + } + } + ] + } + }, + { + "definition": { + "source": { + "$ref": "#/components/sources/localSpecs" + }, + "specs": [ + { + "spec": { + "path": "wsdl/soap.wsdl" + } + } + ] + } + } + ], + "description": "Order API Service" + }, + "productApiService": { + "definitions": [ + { + "definition": { + "source": { + "$ref": "#/components/sources/specsRepo" + }, + "specs": ["api_specs/proto/product-api.proto"] + } + } + ] + }, + "userApiService": { + "definitions": [ + { + "definition": { + "source": { + "$ref": "#/components/sources/specsRepo" + }, + "specs": [ + "api_specs/oas/user-api-oas.yaml", + "api_specs/async/user-api-asyncapi.yaml" + ] + } + } + ] + } + }, + "settings": { + "allMocks": { + "delayInMilliseconds": 100, + "strictMode": false + }, + "myGlobal": { + "backwardCompatibility": { + "baseBranch": "main", + "repoDirectory": "../specs", + "strictMode": true, + "targetPath": "specifications" + }, + "general": { + "disableTelemetry": false, + "featureFlags": { + "escapeSoapAction": false, + "fuzzyMatcherForPayloads": false, + "schemaExampleDefault": true + }, + "ignoreInlineExampleWarnings": false, + "ignoreInlineExamples": false, + "logging": { + "json": { + "console": false, + "directory": "./logs/json", + "logFilePrefix": "specmatic" + }, + "level": "INFO", + "text": { + "console": true, + "directory": "./logs/text", + "logFilePrefix": "specmatic" + } + }, + "prettyPrint": true + }, + "mock": { + "delayInMilliseconds": 250, + "generative": true, + "gracefulRestartTimeoutInMilliseconds": 10000, + "hotReload": true, + "startTimeoutInMilliseconds": 30000, + "strictMode": false + }, + "proxy": { + "ignoreHeaders": ["Authorization", "Cookie"], + "recordRequests": true + }, + "test": { + "junitReportDir": "./build/test-results/specmatic", + "maxTestRequestCombinations": 100, + "parallelism": "4", + "schemaResiliencyTests": "all", + "strictMode": true, + "timeoutInMilliseconds": 120000 + } + }, + "myService": { + "schemaResiliencyTests": "none", + "timeoutInMilliseconds": 45000 + }, + "userApiMock": { + "delayInMilliseconds": 50, + "strictMode": true + } + }, + "sources": { + "localSpecs": { + "filesystem": { + "directory": "./local-specs" + } + }, + "specsRepo": { + "git": { + "auth": { + "bearerFile": "bearer.txt" + }, + "branch": "main", + "matchBranch": true, + "url": "https://github.com/example/specs-repo.git" + } + } + } + }, + "dependencies": { + "data": { + "adapters": { + "$ref": "#/components/adapters/apiServiceHooks" + }, + "dictionary": { + "$ref": "#/components/dictionaries/globalDictionary" + }, + "examples": { + "$ref": "#/components/examples/mockExamples" + } + }, + "services": [ + { + "service": { + "$ref": "#/components/services/userApiService", + "runOptions": { + "$ref": "#/components/runOptions/userApiService" + } + } + }, + { + "service": { + "$ref": "#/components/services/productApiService", + "data": { + "adapters": { + "$ref": "#/components/adapters/productServiceHooks" + }, + "dictionary": { + "$ref": "#/components/dictionaries/productServiceDictionary" + }, + "examples": { + "$ref": "#/components/examples/mockExamples" + } + }, + "runOptions": { + "protobuf": { + "host": "localhost", + "importPaths": ["./proto-imports"], + "port": 10000, + "protocVersion": "3.15.0" + } + }, + "settings": { + "$ref": "#/components/settings/userApiMock" + } + } + } + ], + "settings": { + "$ref": "#/components/settings/allMocks" + } + }, + "mcp": { + "test": { + "baseUrl": "http://localhost:9100", + "bearerToken": "mcp-bearer-token", + "dictionaryFile": "./mcp-dictionary.json", + "enableResiliencyTests": true, + "filterTools": ["tool.alpha", "tool.beta"], + "skipTools": ["tool.gamma"], + "transportKind": "STREAMABLE_HTTP" + } + }, + "proxies": [ + { + "proxy": { + "adapters": { + "$ref": "#/components/adapters/apiServiceHooks" + }, + "baseUrl": "http://localhost:8888", + "cert": { + "$ref": "#/components/certificates/serverCert" + }, + "mock": ["specifications/proxy-api.yaml"], + "recordingsDirectory": "./proxy-recordings/example", + "target": "https://www.example.com/api", + "timeoutInMilliseconds": 15000 + } + }, + { + "proxy": { + "adapters": { + "$ref": "#/components/adapters/apiServiceHooks" + }, + "baseUrl": "http://localhost:9999", + "recordingsDirectory": "./proxy-recordings/foo-bar", + "target": "https://www.foo-bar.com/api" + } + } + ], + "specmatic": { + "governance": { + "report": { + "formats": "${REPORT_FORMAT:[html, ctrf]}", + "outputDirectory": "${REPORT_OUTPUT_DIR:./build/reports/specmatic}" + }, + "successCriteria": { + "enforce": "${ENFORCE_GOVERNANCE_CRITERIA:true}", + "maxMissedOperationsInSpec": "${MAX_MISSED_OPS:5}", + "minCoveragePercentage": "${MIN_COVERAGE:80}" + } + }, + "license": { + "path": "${LICENCE:~/.home/specmatic-license.txt}" + }, + "settings": { + "$ref": "#/components/settings/myGlobal" + } + }, + "systemUnderTest": { + "service": { + "$ref": "#/components/services/orderApiService", + "data": { + "adapters": { + "$ref": "#/components/adapters/apiServiceHooks" + }, + "dictionary": { + "$ref": "#/components/dictionaries/globalDictionary" + }, + "examples": { + "$ref": "#/components/examples/testExamples" + } + }, + "runOptions": { + "$ref": "#/components/runOptions/orderApiService" + }, + "settings": { + "$ref": "#/components/settings/myService" + } + } + }, + "version": 3 +} diff --git a/src/test/specmatic/specmatic.json b/src/test/specmatic/specmatic-v2.json similarity index 98% rename from src/test/specmatic/specmatic.json rename to src/test/specmatic/specmatic-v2.json index c6861cb783c..62bd97bbfdc 100644 --- a/src/test/specmatic/specmatic.json +++ b/src/test/specmatic/specmatic-v2.json @@ -15,7 +15,6 @@ "src/test/petstore.yaml", { "basePath": "/v1", - "baseUrl": "https://api.example.com", "host": "api.example.com", "port": 443, "specs": ["src/test/payments.yaml"] @@ -28,6 +27,7 @@ "provides": [ "src/test/petstore.yaml", { + "basePath": "/v1", "host": "localhost", "port": 8080, "resiliencyTests": { diff --git a/src/test/specmatic/specmatic-v3-dereffed.json b/src/test/specmatic/specmatic-v3-dereffed.json new file mode 100644 index 00000000000..8dcedfbb7d2 --- /dev/null +++ b/src/test/specmatic/specmatic-v3-dereffed.json @@ -0,0 +1,69 @@ +{ + "dependencies": { + "services": [ + { + "service": { + "definitions": [ + { + "definition": { + "source": { + "filesystem": { + "directory": "." + } + }, + "specs": ["product_search_bff_v5.yaml"] + } + } + ], + "runOptions": { + "openapi": { + "baseUrl": "http://0.0.0.0:9090", + "type": "mock" + } + } + } + } + ] + }, + "specmatic": { + "governance": { + "report": { + "outputDirectory": "file:///usr/src/app/build/reports/specmatic/" + }, + "successCriteria": { + "enforce": true, + "minCoveragePercentage": 70 + } + }, + "settings": { + "general": { + "prettyPrint": true + } + } + }, + "systemUnderTest": { + "service": { + "definitions": [ + { + "definition": { + "source": { + "filesystem": { + "directory": "." + } + }, + "specs": ["product_search_bff_v5.yaml"] + } + } + ], + "runOptions": { + "openapi": { + "baseUrl": "http://studio:9090" + } + }, + "settings": { + "schemaResiliencyTests": "all" + } + } + }, + "version": 3 +} diff --git a/src/test/specmatic/specmatic-v3-reffed.json b/src/test/specmatic/specmatic-v3-reffed.json new file mode 100644 index 00000000000..30ed0293e0d --- /dev/null +++ b/src/test/specmatic/specmatic-v3-reffed.json @@ -0,0 +1,73 @@ +{ + "components": { + "runOptions": { + "productSearchBffV5": { + "openapi": { + "baseUrl": "http://studio:9090", + "type": "mock" + } + } + }, + "services": { + "productSearchBffV5": { + "definitions": [ + { + "definition": { + "source": { + "filesystem": { + "directory": "." + } + }, + "specs": ["product_search_bff_v5.yaml"] + } + } + ] + } + }, + "settings": { + "productSearchBffV5": { + "schemaResiliencyTests": "all" + } + } + }, + "dependencies": { + "services": [ + { + "service": { + "$ref": "#/components/services/productSearchBffV5", + "runOptions": { + "$ref": "#/components/runOptions/productSearchBffV5" + } + } + } + ] + }, + "specmatic": { + "governance": { + "report": { + "outputDirectory": "file:///usr/src/app/build/reports/specmatic/" + }, + "successCriteria": { + "enforce": true, + "minCoveragePercentage": 70 + } + }, + "settings": { + "general": { + "prettyPrint": true + } + } + }, + "systemUnderTest": { + "service": { + "$ref": "#/components/services/productSearchBffV5", + "runOptions": { + "$ref": "#/components/runOptions/productSearchBffV5" + }, + "settings": { + "$ref": "#/components/settings/productSearchBffV5" + } + } + }, + "version": 3 +}