pact-jvm-provider - JUnit5 Spring - Unable to add authorization headers

1.6k Views Asked by At

I have a Spring Boot application for which I'm writing contract tests using Pact-JVM. It is a provider.

I have added the following pact dependencies/configurations in build.gradle: I'm using Java 11, Gradle 6.3

plugins {
    id 'au.com.dius.pact' version '4.1.6'
}
dependencies {
    testImplementation 'ch.qos.logback:logback-core:1.2.3'
    testImplementation 'ch.qos.logback:logback-classic:1.2.3'

    testImplementation 'au.com.dius.pact.provider:junit5:4.1.6'
}

Here is my verification test:

@Provider("product")
@PactBroker(host = "localhost", scheme = "http", port = "9292")
class PactVerificationTest {

    @BeforeEach
    void setupTestTarget(PactVerificationContext context) {
        context.setTarget(new HttpTestTarget("localhost", 9002, "/"));
    }

    @TargetRequestFilter
    public void addAuthorizationHeadersStripContextPathRequestFilter(HttpRequest request) throws URISyntaxException {
        request.addHeader("USER_ID", "1231324123414");
        request.addHeader("AB_USER", "1231324123414");
        request.addHeader("AB_USERGROUP", "installtrial");

        String rawUri = request.getRequestLine().getUri();
        ((HttpRequestBase) request).setURI(new URI(rawUri.replaceFirst("/product/", "/")));
    }

    @TestTemplate
    @ExtendWith(PactVerificationInvocationContextProvider.class)
    void pactVerificationTestTemplate(PactVerificationContext context) {
        context.verifyInteraction();
    }

    @State("Given products available")
    public void testProductDetails() {

    }
}

I am expecting the authorization headers added in TargetRequestFilter annotated method to be part of the request but those headers are missing from the request. Can you help me out what I'm doing wrong here?

Also, I am looking for an example using the latest version of pact-jvm. I couldn't find in the examples provided by pact-jvm.

2

There are 2 best solutions below

0
On BEST ANSWER

Pact-JVM Slack team came to the rescue!

In the case of Pact-JVM + JUnit5, adding headers/request manipulation can be done in @TestTemplate annotated method itself - https://docs.pact.io/implementation_guides/jvm/provider/junit5/#modifying-the-requests-before-they-are-sent

Now my method looks like this:

@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactVerificationTestTemplate(PactVerificationContext context, HttpRequest request) {
    addAuthenticationHeaders(request);
    context.verifyInteraction();
}
0
On

In case you'd like to dynamically change the authorization headers, that's how we do it. Here we start the tests as a teacher and when needed we call the method to overwrite the access token with the student token.

@Provider(PACT_PROVIDER)
@Consumer(PACT_CONSUMER)
@PactBroker(host = BROKER_PACT_URL)
public class PactProviderGcTest {

@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactTestTemplate(PactVerificationContext context, HttpRequest request) {

    request.addHeader("Authorization", "Bearer " + accessToken);

    context.verifyInteraction();
}

@BeforeAll
public static void setUp() throws JSONException {
  accessToken =  getTeacherAccessToken();
}

@BeforeEach
void before(PactVerificationContext context) {
    context.setTarget(new HttpsTestTarget(BASE_PACT_URL, 443, "/"));
}

@State("A request to retrieve google courses as a teacher")
void sampleState() {}

@State("A request to retrieve a google course as a teacher")
void sampleState1() {}

@State("A request to turn in a submission as a student")
void sampleState2() throws JSONException {
    accessToken = getAccessTokenStudent();
}

}

// Get token methods

public static String getTeacherAccessToken() {

    accessToken = retrieveTokenFor("Teacher");

    return accessToken;
}

public static String getAccessTokenStudent() throws JSONException {

   accessToken = retrieveTokenFor("Student");

   return accessToken;
}