Skip to content

Commit

Permalink
feat(compatibility-suite): Add V4 message scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
rholshausen committed Aug 16, 2023
1 parent bd43f8a commit c44b05a
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,19 @@ class MessageConsumer {
builder.build()
}
}

@Given('a key of {string} is specified for the message interaction')
void a_key_of_is_specified_for_the_message_interaction(String key) {
builder.key(key)
}

@Given('the message interaction is marked as pending')
void the_message_interaction_is_marked_as_pending() {
builder.pending(true)
}

@Given('a comment {string} is added to the message interaction')
void a_comment_is_added_to_the_message_interaction(String comment) {
builder.comment(comment)
}
}
117 changes: 117 additions & 0 deletions compatibility-suite/src/test/groovy/steps/v4/MessageProvider.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package steps.v4

import au.com.dius.pact.core.model.Consumer
import au.com.dius.pact.core.model.DefaultPactWriter
import au.com.dius.pact.core.model.Pact
import au.com.dius.pact.core.model.PactSpecVersion
import au.com.dius.pact.core.model.Provider
import au.com.dius.pact.core.model.StringSource
import au.com.dius.pact.core.model.V4Interaction
import au.com.dius.pact.core.model.V4Pact
import au.com.dius.pact.core.model.v4.MessageContents
import au.com.dius.pact.provider.ConsumerInfo
import au.com.dius.pact.provider.MessageAndMetadata
import au.com.dius.pact.provider.PactVerification
import au.com.dius.pact.provider.ProviderInfo
import io.cucumber.datatable.DataTable
import io.cucumber.java.en.Given
import steps.shared.SharedHttpProvider
import steps.shared.VerificationData

import static steps.shared.SharedSteps.configureBody
import static steps.shared.SharedSteps.determineContentType

class MessageProvider {
SharedHttpProvider sharedProvider
VerificationData verificationData
def messages = [:]

def messageFactory = { String desc ->
messages[desc]
}

MessageProvider(SharedHttpProvider sharedProvider, VerificationData verificationData) {
this.sharedProvider = sharedProvider
this.verificationData = verificationData
}

static V4Interaction.AsynchronousMessage configureMessage(String name, String fixture) {
def part = configureBody(fixture, determineContentType(fixture, null))
def contents = new MessageContents(part.body)
contents.metadata.putAll(part.headers.collectEntries {
if (it.value.size() == 0) {
[it.key, null]
} else if (it.value.size() == 1) {
[it.key, it.value.first()]
} else {
[it.key, it.value]
}
})
new V4Interaction.AsynchronousMessage(name, [], contents)
}

@Given('a provider is started that can generate the {string} message with {string}')
void a_provider_is_started_that_can_generate_the_message(String name, String fixture) {
def part = configureBody(fixture, determineContentType(fixture, null))
def message = new MessageAndMetadata(part.body.value, part.headers.collectEntries {
if (it.value.size() == 0) {
[it.key, null]
} else if (it.value.size() == 1) {
[it.key, it.value.first()]
} else {
[it.key, it.value]
}
})
messages[name] = message

verificationData.providerInfo = new ProviderInfo('p')
verificationData.providerInfo.verificationType = PactVerification.RESPONSE_FACTORY
verificationData.providerInfo.stateChangeTeardown = true
verificationData.responseFactory = messageFactory
}

@Given('a Pact file for {string}:{string} is to be verified, but is marked pending')
void a_pact_file_for_is_to_be_verified_but_is_marked_pending(String name, String fixture) {
def message = configureMessage(name, fixture)
message.pending = true
Pact pact = new V4Pact(new Consumer('v4-compatibility-suite-c'), new Provider('p'), [message])
StringWriter writer = new StringWriter()
writer.withPrintWriter {
DefaultPactWriter.INSTANCE.writePact(pact, it, PactSpecVersion.V4)
}
ConsumerInfo consumerInfo = new ConsumerInfo('c')
consumerInfo.pactSource = new StringSource(writer.toString())
if (verificationData.providerInfo.stateChangeRequestFilter) {
consumerInfo.stateChange = verificationData.providerInfo.stateChangeRequestFilter
}
verificationData.providerInfo.consumers << consumerInfo
}

@Given('a Pact file for {string}:{string} is to be verified with the following comments:')
void a_pact_file_for_is_to_be_verified_with_the_following_comments(String name, String fixture, DataTable dataTable) {
def message = configureMessage(name, fixture)

for (comment in dataTable.asMaps()) {
switch (comment['type']) {
case 'text':
message.addTextComment(comment['comment'])
break
case 'testname':
message.setTestName(comment['comment'])
break
}
}

Pact pact = new V4Pact(new Consumer('v4-compatibility-suite-c'), new Provider('p'), [message])
StringWriter writer = new StringWriter()
writer.withPrintWriter {
DefaultPactWriter.INSTANCE.writePact(pact, it, PactSpecVersion.V4)
}
ConsumerInfo consumerInfo = new ConsumerInfo('c')
consumerInfo.pactSource = new StringSource(writer.toString())
if (verificationData.providerInfo.stateChangeRequestFilter) {
consumerInfo.stateChange = verificationData.providerInfo.stateChangeRequestFilter
}
verificationData.providerInfo.consumers << consumerInfo
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@ class SharedV4Steps {
def json = JsonParser.parseString(value)
assert interactions.get(index)[name] == json
}

@Then('there will be an interaction in the Pact file with a type of {string}')
void there_will_be_an_interaction_in_the_pact_file_with_a_type_of(String type) {
JsonValue.Array interactions = pactJson['interactions'].asArray()
assert interactions.values.find { it['type'] == type } != null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,64 @@ open class MessageInteractionBuilder(
}
}

/**
* Sets the unique key for the interaction. If this is not set, or is empty, a key will be calculated from the
* contents of the interaction.
*/
fun key(key: String?): MessageInteractionBuilder {
interaction.key = key
return this;
}

/**
* Sets the interaction description
*/
fun description(description: String): MessageInteractionBuilder {
interaction.description = description
return this
}

/**
* Adds a provider state to the interaction.
*/
@JvmOverloads
fun state(stateDescription: String, params: Map<String, Any?> = emptyMap()): MessageInteractionBuilder {
interaction.providerStates.add(ProviderState(stateDescription, params))
return this
}

/**
* Adds a provider state to the interaction with a parameter.
*/
fun state(stateDescription: String, paramKey: String, paramValue: Any?): MessageInteractionBuilder {
interaction.providerStates.add(ProviderState(stateDescription, mapOf(paramKey to paramValue)))
return this
}

/**
* Adds a provider state to the interaction with parameters a pairs of key/values.
*/
fun state(stateDescription: String, vararg params: Pair<String, Any?>): MessageInteractionBuilder {
interaction.providerStates.add(ProviderState(stateDescription, params.toMap()))
return this
}

/**
* Marks the interaction as pending.
*/
fun pending(pending: Boolean): MessageInteractionBuilder {
interaction.pending = pending
return this
}

/**
* Adds a text comment to the interaction
*/
fun comment(comment: String): MessageInteractionBuilder {
interaction.addTextComment(comment)
return this
}

fun build(): V4Interaction {
return interaction
}
Expand Down

0 comments on commit c44b05a

Please sign in to comment.