All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.aws.smithy.kotlin.runtime.httptest.CallAsserter.kt Maven / Gradle / Ivy

/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */
package aws.smithy.kotlin.runtime.httptest

import aws.smithy.kotlin.runtime.http.readAll
import aws.smithy.kotlin.runtime.http.request.HttpRequest
import kotlin.test.assertEquals
import kotlin.test.assertTrue

/**
 * Asserts equality between two [HttpRequest] instances. Implementations of this interface are free to choose criteria
 * for the equality assertion.
 */
public interface CallAsserter {
    /**
     * Verify that [expected] and [actual] are equal according to this asserter's criteria. If not, an [AssertionError]
     * is thrown.
     * @param msgPrefix The prefix to include in the message if an [AssertionError] is thrown
     * @param expected The expected request
     * @param actual The actual request
     */
    public suspend fun assertEquals(msgPrefix: String, expected: HttpRequest, actual: HttpRequest)

    public companion object {
        /**
         * Asserter that verifies every part of the requests match
         */
        public val FullyMatching: CallAsserter = List(
            MatchingMethods,
            MatchingUrls,
            MatchingHeaders.All,
            MatchingBodies,
        )
    }

    /**
     * Asserter that delegates to a collection of sub-asserters
     */
    public class List(private vararg val asserters: CallAsserter) : CallAsserter {
        override suspend fun assertEquals(msgPrefix: String, expected: HttpRequest, actual: HttpRequest) {
            asserters.forEach { it.assertEquals(msgPrefix, expected, actual) }
        }
    }

    /**
     * Asserter that verifies the methods of the requests match
     */
    public object MatchingMethods : CallAsserter {
        override suspend fun assertEquals(msgPrefix: String, expected: HttpRequest, actual: HttpRequest) {
            assertEquals(expected.method, actual.method, "$msgPrefix: Method mismatch")
        }
    }

    /**
     * Asserter that verifies the URLs of the requests match
     */
    public object MatchingUrls : CallAsserter {
        override suspend fun assertEquals(msgPrefix: String, expected: HttpRequest, actual: HttpRequest) {
            assertEquals(expected.url.toString(), actual.url.toString(), "$msgPrefix: URL mismatch")
        }
    }

    /**
     * Asserter that verifies headers of the requests match
     * @param shouldVerifyHeader A predicate which indicates whether a header with the given key should be verified
     */
    public class MatchingHeaders(private val shouldVerifyHeader: (String) -> Boolean) : CallAsserter {
        override suspend fun assertEquals(msgPrefix: String, expected: HttpRequest, actual: HttpRequest) {
            expected.headers.forEach { name, values ->
                if (shouldVerifyHeader(name)) {
                    values.forEach {
                        assertTrue(actual.headers.contains(name, it), "$msgPrefix: header `$name` missing value `$it`")
                    }
                }
            }
        }

        public companion object {
            /**
             * Asserter that verifies every header of the requests match
             */
            public val All: MatchingHeaders = MatchingHeaders { true }
        }
    }

    /**
     * Asserter that verifies the bodies of the requests match
     */
    public object MatchingBodies : CallAsserter {
        override suspend fun assertEquals(msgPrefix: String, expected: HttpRequest, actual: HttpRequest) {
            val expectedBody = expected.body.readAll()?.decodeToString()
            val actualBody = actual.body.readAll()?.decodeToString()
            assertEquals(expectedBody, actualBody, "$msgPrefix: body mismatch")
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy