[[contract-common-top-elements]]
= Common Top-Level Elements

include::partial$_attributes.adoc[]

The following sections describe the most common top-level elements:

* xref:project-features-contract/common-top-elements.adoc#contract-dsl-description[Description]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-name[Name]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-ignoring-contracts[Ignoring Contracts]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-in-progress[Contracts in Progress]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-passing-values-from-files[Passing Values from Files]
* xref:project-features-contract/common-top-elements.adoc#contract-dsl-metadata[Metadata]

[[contract-dsl-description]]
== Description

You can add a `description` to your contract. The description is arbitrary text. The
following code shows an example:

====
[source,groovy,indent=0,role="primary"]
.Groovy
----
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=description,indent=0]
----

[source,yaml,indent=0,role="secondary"]
.YAML
----
include::{verifier_root_path}/src/test/resources/yml/contract_rest.yml[indent=0]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=description,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.Kotlin
----
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=description,indent=0]
----
====

[[contract-dsl-name]]
== Name

You can provide a name for your contract. Assume that you provide the following name:
`should register a user`. If you do so, the name of the autogenerated test is
`validate_should_register_a_user`. Also, the name of the stub in a WireMock stub is
`should_register_a_user.json`.

IMPORTANT: You must ensure that the name does not contain any characters that make the
generated test not compile. Also, remember that, if you provide the same name for
multiple contracts, your autogenerated tests fail to compile and your generated stubs
override each other.

The following example shows how to add a name to a contract:

====
[source,groovy,indent=0,role="primary"]
.Groovy
----
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=name,indent=0]
----

[source,yaml,indent=0,role="secondary"]
.YAML
----
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=name,indent=0]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=name,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.Kotlin
----
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=name,indent=0]
----
====

[[contract-dsl-ignoring-contracts]]
== Ignoring Contracts

If you want to ignore a contract, you can either set a value for ignored contracts in the
plugin configuration or set the `ignored` property on the contract itself. The following
example shows how to do so:

====
[source,groovy,indent=0,role="primary"]
.Groovy
----
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=ignored,indent=0]
----

[source,yaml,indent=0,role="secondary"]
.YAML
----
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=ignored,indent=0]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=ignored,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.Kotlin
----
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=ignored,indent=0]
----
====

[[contract-dsl-in-progress]]
== Contracts in Progress

A contract in progress does not generate tests on the producer side but does allow generation of stubs.

IMPORTANT: Use this feature with caution as it may lead to false positives, because you generate stubs for your consumers to use without actually having the implementation in place.

If you want to set a contract in progress, the following
example shows how to do so:

====
[source,groovy,indent=0,role="primary"]
.Groovy
----
include::{contract_spec_tests_path}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ContractSpec.groovy[tags=in_progress,indent=0]
----

[source,yaml,indent=0,role="secondary"]
.YAML
----
include::{verifier_root_path}/src/test/resources/yml/contract.yml[tags=in_progress,indent=0]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=in_progress,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.Kotlin
----
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=in_progress,indent=0]
----
====

You can set the value of the `failOnInProgress` Spring Cloud Contract plugin property to ensure that your build breaks when at least one contract in progress remains in your sources.

[[contract-dsl-passing-values-from-files]]
== Passing Values from Files

Starting with version `1.2.0`, you can pass values from files. Assume that you have the
following resources in your project:

[source,bash,indent=0]
----
└── src
    └── test
        └── resources
            └── contracts
                ├── readFromFile.groovy
                ├── request.json
                └── response.json
----

Further assume that your contract is as follows:

====
[source,groovy,indent=0,role="primary"]
.Groovy
----
include::{verifier_root_path}/src/test/resources/classpath/readFromFile.groovy[indent=0]
----

[source,yaml,indent=0,role="secondary"]
.YAML
----
include::{verifier_root_path}/src/test/resources/yml/contract_from_file.yml[indent=0]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_from_file.java[tags=class,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.Kotlin
----
include::{verifier_root_path}/src/test/resources/kotlin/readFromFile.kts[tags=class,indent=0]
----
====

Further assume that the JSON files are as follows:

====
[source,json,indent=0,subs="verbatim",role="primary"]
.request.json
----
include::{verifier_root_path}/src/test/resources/classpath/request.json[indent=0]
----

[source,groovy,indent=0,subs="verbatim",role="secondary"]
.response.json
----
include::{verifier_root_path}/src/test/resources/classpath/response.json[indent=0]
----
====

When test or stub generation takes place, the contents of the `request.json` and `response.json` files are passed to the body
of a request or a response. The name of the file needs to be a file in a location
relative to the folder in which the contract resides.

If you need to pass the contents of a file in binary form,
you can use the `fileAsBytes` method in the coded DSL or a `bodyFromFileAsBytes` field in YAML.

The following example shows how to pass the contents of binary files:

====
[source,groovy,indent=0,role="primary"]
.Groovy
----
include::{verifier_root_path}/src/test/resources/body_builder/worksWithPdf.groovy[indent=0]
----

[source,yaml,indent=0,role="secondary"]
.YAML
----
include::{verifier_root_path}/src/test/resources/yml/contract_pdf.yml[indent=0]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_from_pdf.java[tags=class,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.Kotlin
----
include::{contract_kotlin_spec_path}/src/test/resources/contracts/shouldWorkWithBinaryPayload.kts[tags=class,indent=0]
----
====

IMPORTANT: You should use this approach whenever you want to work with binary payloads,
both for HTTP and messaging.

[[contract-dsl-metadata]]
== Metadata

You can add `metadata` to your contract. Via the metadata you can pass in configuration to extensions. Below you can find
an example of using the `wiremock` key. Its value is a map whose key is `stubMapping` and value being WireMock's `StubMapping` object. Spring Cloud Contract is able to
patch parts of your generated stub mapping with your custom code. You may want to do that in order to add webhooks, custom
delays or integrate with third party WireMock extensions.

{samples_code}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldReturnFraudStats.groovy[Click here to see the Groovy code]

{samples_code}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldReturnFraudStats.yml[Click here to see the YAML code]

====
[source,java,indent=0,subs="verbatim",role="secondary"]
.java
----
include::{verifier_root_path}/src/test/resources/contractsToCompile/contract_rest_with_tags.java[tags=metadata,indent=0]
----

[source,kotlin,indent=0,subs="verbatim",role="secondary"]
.kotlin
----
include::{contract_kotlin_spec_path}/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt[tags=metadata,indent=0]
----
====

In the following sections you can find examples of the supported metadata entries.

////
include::{project-root}/docs/target/metadata.adoc[indent=0]
////

[[features-http]]
== Contracts for HTTP

Spring Cloud Contract lets you verify applications that use REST or HTTP as a
means of communication. Spring Cloud Contract verifies that, for a request that matches the
criteria from the `request` part of the contract, the server provides a response that is in
keeping with the `response` part of the contract. Subsequently, the contracts are used to
generate WireMock stubs that, for any request matching the provided criteria, provide a
suitable response.

