Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pending interactions in pact-jvm #1707

Closed
holomekc opened this issue Aug 18, 2023 · 4 comments
Closed

Pending interactions in pact-jvm #1707

holomekc opened this issue Aug 18, 2023 · 4 comments
Labels
question Indicates that an issue, pull request, or discussion needs more information

Comments

@holomekc
Copy link
Contributor

Hi,
I found this issue pact-foundation/pact-specification/issues/73 and I was wondering how I can set this in pact-jvm. I could find that the model contains the value:


But I am not sure how I can set this in my consumer test. I searched in the @Pact annotation and also via the PactDslWithProvider, which we are using to define our expectations. But I could not find a way to do so.

What is the appropriate way to set this pending state?

Br,
Chris

PS: Is there a documentation regarding this value? I can only find the pending pacts docs, but nothing regarding pending interactions set by the consumer.

@rholshausen
Copy link
Contributor

If you use the PactBuilder class, and one of the expectsToReceive methods (i.e. expectsToReceiveHttpInteraction), the child builders have a method to set the pending flag.

For example:

.expectsToReceiveHttpInteraction("V4 PactProviderTest test interaction", httpBuilder -> {
        return httpBuilder
          .withRequest(requestBuilder -> requestBuilder
            .path("/")
            .method("GET"))
          .willRespondWith(responseBuilder -> responseBuilder
            .status(200)
            .body("{\"responsetest\": true, \"version\": \"v3\"}")
            .header("test", notEmpty("Example"))
          )
          .pending(true); // <---
      })

@rholshausen rholshausen added the question Indicates that an issue, pull request, or discussion needs more information label Aug 18, 2023
@holomekc
Copy link
Contributor Author

Thx for the incredible fast feedback. This works. Thank you so much.

@github-project-automation github-project-automation bot moved this from New Issue to Closed in Pact Triage (not yet in use) Aug 18, 2023
@holomekc
Copy link
Contributor Author

Hi
Sorry to reopen this again. The PactBuilder indicates that PactDslWithProvider and MessagePactBuilder are legacy, but the SynchronousMessagePactBuilder is not?

/**
* Use the old HTTP Pact DSL
*/
fun usingLegacyDsl(): PactDslWithProvider {
return PactDslWithProvider(ConsumerPactBuilder(consumer), provider, pactVersion)
}
/**
* Use the old Message Pact DSL
*/
fun usingLegacyMessageDsl(): MessagePactBuilder {
return MessagePactBuilder(pactVersion).consumer(consumer).hasPactWith(provider)
}
/**
* Use the Synchronous Message DSL
*/
fun usingSynchronousMessageDsl(): SynchronousMessagePactBuilder {
return SynchronousMessagePactBuilder(pactVersion).consumer(consumer).hasPactWith(provider)
}

But then how to achieve the same with Async? I can use the PactBuilder and set the pending flag, but then I am facing issues with creating the content of my expectations.

I could find:
/**

  • Configure the interaction using a builder supplied by the plugin author.
    */
    fun with(builder: PluginInteractionBuilder): PactBuilder {
    require(currentInteraction != null) {
    "'with' must be preceded by 'expectsToReceive'"
    }
    return with(builder.build())
    }
    But there seems to be no provided PactInteractionBuilder for Async.

The other option is:

/**
* Values to configure the interaction. In the case of an interaction configured by a plugin, you need to follow
* the plugin documentation of what values must be specified here.
*/
@Suppress("ComplexMethod")
fun with(values: Map<String, Any?>): PactBuilder {
require(currentInteraction != null) {
"'with' must be preceded by 'expectsToReceive'"
}

but then I would need to guess message.contents and write alle matching rules as text.

is V4Interaction.AsynchronousMessage -> {
logger.debug { "Configuring AsynchronousMessage interaction from $values" }
if (values.containsKey("message.contents")) {
val messageContents = setupMessageContents(this, values["message.contents"], interaction)
if (messageContents.size > 1) {
logger.warn { "Received multiple values for the interaction contents, will only use the first" }
}
val contents = messageContents.first()
interaction.contents = contents.first
if (contents.second.isNotEmpty()) {
interaction.interactionMarkup = contents.second
}
}
interaction.updateProperties(values.filter { it.key != "message.contents" })
}

Is there a way to use a builder here and not just a map?

@rholshausen
Copy link
Contributor

I've added the missing methods to SynchronousMessagePactBuilder.

You can also use PactBuilder.expectsToReceiveSynchronousMessageInteraction which works in the same way as the other interaction builders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Indicates that an issue, pull request, or discussion needs more information
Projects
Status: Closed
Development

No branches or pull requests

2 participants