<commit_before>package org.pac4j.async.vertx

import io.vertx.core.buffer.Buffer
import io.vertx.ext.web.client.HttpRequest
import io.vertx.ext.web.client.HttpResponse
import io.vertx.ext.web.client.WebClient
import io.vertx.core.Vertx
import io.vertx.ext.web.client.WebClientOptions
import io.vertx.kotlin.coroutines.awaitResult
import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
 * Test client to wrap a set of http calls to our test server. We will also record any state (such as session cookies)
 * within this client for reuse
 */
class TestClient(val vertx: Vertx) {

    val cookieHolder: SessionCookieHolder = SessionCookieHolder()
    val client: WebClient = WebClient.create(vertx, WebClientOptions().setFollowRedirects(false))

    companion object {
        val LOG: Logger = LoggerFactory.getLogger(TestClient.javaClass)
    }

    suspend fun retrievingSessionCookie(processing: suspend () -> HttpResponse<Buffer>): HttpResponse<Buffer> {
        val response = processing()
        val cookie = response.headers().get("set-cookie")
        cookieHolder.persist(cookie)
        return response
    }

    suspend fun usingSessionCookie(processing: suspend () -> HttpRequest<Buffer>): HttpRequest<Buffer> {
        val request = processing()
        if (cookieHolder.retrieve() != null) {
            request.headers().set("cookie", cookieHolder.retrieve())
        }
        return request
    }

    suspend fun spoofLogin() {

        LOG.info("Spoofing login")
        val request = usingSessionCookie { client.post(8080, "localhost", "/spoofLogin") }
        val response: HttpResponse<Buffer> = retrievingSessionCookie {
            awaitResult { request.send(it) }
        }
        if (response.statusCode() != 204) {
            // We should fail now
            LOG.info("statusCode: " + response.statusCode())
            throw RuntimeException("Failed to spoof login")
        }
        LOG.info("spoofLogin succeeded")
    }

    suspend fun getSecuredEndpoint(): HttpResponse<Buffer> {
        LOG.info("Retrieving secured endpoint§")
        val request = usingSessionCookie { client.get(8080, "localhost", "/profile")}
        return awaitResult { request.send(it) }
    }

}<commit_msg>pac4j-async-334 Add withRequestDecorator to test client to enable the next request to be decorated<commit_after>package org.pac4j.async.vertx

import io.vertx.core.buffer.Buffer
import io.vertx.ext.web.client.HttpRequest
import io.vertx.ext.web.client.HttpResponse
import io.vertx.ext.web.client.WebClient
import io.vertx.core.Vertx
import io.vertx.ext.web.client.WebClientOptions
import io.vertx.kotlin.coroutines.awaitResult
import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
 * Test client to wrap a set of http calls to our test server. We will also record any state (such as session cookies)
 * within this client for reuse
 */
class TestClient(val vertx: Vertx) {

    val cookieHolder: SessionCookieHolder = SessionCookieHolder()
    val client: WebClient = WebClient.create(vertx, WebClientOptions().setFollowRedirects(false))

    /**
     * Decorator for requests to secured endpoint. Aim being to enable intentional authentication success or
     * failure on the test direct client, for known test scenarios.
     */
    var requestDecorator: (HttpRequest<Buffer>) -> HttpRequest<Buffer> = { request: HttpRequest<Buffer> -> request }

    companion object {
        val LOG: Logger = LoggerFactory.getLogger(TestClient.javaClass)
    }

    suspend fun retrievingSessionCookie(processing: suspend () -> HttpResponse<Buffer>): HttpResponse<Buffer> {
        val response = processing()
        val cookie = response.headers().get("set-cookie")
        cookieHolder.persist(cookie)
        return response
    }

    suspend fun usingSessionCookie(processing: suspend () -> HttpRequest<Buffer>): HttpRequest<Buffer> {
        val request = processing()
        if (cookieHolder.retrieve() != null) {
            request.headers().set("cookie", cookieHolder.retrieve())
        }
        return request
    }

    suspend fun spoofLogin() {

        LOG.info("Spoofing login")
        val request = usingSessionCookie { client.post(8080, "localhost", "/spoofLogin") }
        val response: HttpResponse<Buffer> = retrievingSessionCookie {
            awaitResult { request.send(it) }
        }
        if (response.statusCode() != 204) {
            // We should fail now
            LOG.info("statusCode: " + response.statusCode())
            throw RuntimeException("Failed to spoof login")
        }
        LOG.info("spoofLogin succeeded")
    }

    suspend fun getSecuredEndpoint(): HttpResponse<Buffer> {
        LOG.info("Retrieving secured endpoint§")
        val request = usingSessionCookie { requestDecorator(client.get(8080, "localhost", "/profile")) }
        requestDecorator = { request -> request }
        return awaitResult { request.send(it) }
    }

    suspend fun withRequestDecorator(decorator: ((HttpRequest<Buffer>) -> Unit)) {
        requestDecorator = { request ->
            decorator(request)
            request
        }
    }

}
{'fraction_non_alphanumeric': 0.1053662358010184, 'fraction_numerical': 0.00626713670191931, 'mean_word_length': 3.1185483870967743, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4232506', 'n_tokens_mistral': 1430, 'n_tokens_neox': 1390, 'n_words': 350}