diff --git a/README.md b/README.md
index b375faa..8ee4c31 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,8 @@ Network transactions from previous sessions have a background in light gray colo
3. [Data retention policy](docs/DATA_RETENTION_POLICY.md)
4. [Shortcut for mobile clients](docs/SHORTCUT_FOR_MOBILE_CLIENTS.md)
5. [Excluding Inspektify from Release Builds](docs/EXCLUDING_INSPEKTIFY_FROM_RELEASE_BUILDS.md)
-5. [Redact data from Inspektify](docs/EXCLUDING_INSPEKTIFY_FROM_RELEASE_BUILDS.md)
+6. [Redact data from Inspektify](docs/EXCLUDING_INSPEKTIFY_FROM_RELEASE_BUILDS.md)
+7. [Ignore endpoints configuration](docs/IGNORE_ENDPOINTS_CONFIGURATION.md)
## Sample project
@@ -137,4 +138,7 @@ the sample is configured to use Ktor from the 3.x.x family, but if you want to t
-
\ No newline at end of file
+
+
+## Sponsor my work
+
\ No newline at end of file
diff --git a/docs/IGNORE_ENDPOINTS_CONFIGURATION.md b/docs/IGNORE_ENDPOINTS_CONFIGURATION.md
new file mode 100644
index 0000000..096a10c
--- /dev/null
+++ b/docs/IGNORE_ENDPOINTS_CONFIGURATION.md
@@ -0,0 +1,44 @@
+# Ignore endpoints configuration
+
+You can exclude specific endpoints from interception and logging by configuring
+the `ignoreEndpoints` property in `InspektifyKtorConfig`. This is a list of `IgnorePathData`
+objects, where each object specifies the HTTP method, the endpoint, and the matching strategy.
+
+```
+install(InspektifyKtor) {
+ ignoreEndpoints = listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/health-check")
+ ),
+ IgnorePathData(
+ method = MethodType.POST,
+ matchingStrategy = EndpointMatchingStrategy.Contains("/login")
+ ),
+ IgnorePathData(
+ method = MethodType.ALL,
+ matchingStrategy = EndpointMatchingStrategy.Regex("https://reqres\\.in/.*"),
+ )
+ )
+}
+```
+
+## IgnorePathData Fields
+
+- `method`: Defines the HTTP method to match, using MethodType (e.g., GET, POST).
+- `endpointMatchingStrategy`: Defines in which way matching should happen when ignoring different
+ endpoints
+
+### MethodType property
+
+Supported HTTP methods: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`.
+
+There is a special case added to ignore all of HTTP methods if someone would like to ignore all
+traffic coming in from specific endpoint. If you want to do that you can use `ALL` as methodType and
+all traffic will be ignored that will match defined strategy.
+
+### EndpointMatchingStrategy property
+
+`Exact`: Exact URL matching.
+`Contains`: Substring matching within the URL.
+`Regex`: Matching URL against regular expression.
\ No newline at end of file
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/InspektifyKtorConfig.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/InspektifyKtorConfig.kt
index 93e5290..5baae23 100644
--- a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/InspektifyKtorConfig.kt
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/InspektifyKtorConfig.kt
@@ -7,6 +7,7 @@ public class InspektifyKtorConfig {
public var dataRetentionPolicy: DataRetentionPolicy = DataRetentionPolicy.DayDuration(14)
public var redactHeaders: List = emptyList()
public var redactBodyProperties: List = emptyList()
+ public var ignoreEndpoints: List = emptyList()
}
public sealed interface LogLevel {
@@ -31,5 +32,26 @@ public sealed interface DataRetentionPolicy {
public data class SessionCount(val numOfSessions: Int) : DataRetentionPolicy
}
+public data class IgnorePathData(val method: MethodType, val matchingStrategy: EndpointMatchingStrategy)
+
+public enum class MethodType(internal val value: String) {
+ GET("GET"),
+ POST("POST"),
+ PUT("PUT"),
+ DELETE("DELETE"),
+ PATCH("PATCH"),
+ HEAD("HEAD"),
+ OPTIONS("OPTIONS"),
+ ALL("*");
+
+ internal fun isAll(): Boolean = this == ALL
+}
+
+public sealed interface EndpointMatchingStrategy {
+ public data class Exact(val value: String) : EndpointMatchingStrategy
+ public data class Contains(val value: String) : EndpointMatchingStrategy
+ public data class Regex(val value: String) : EndpointMatchingStrategy
+}
+
internal const val INSPEKTIFY_SHORTCUT_ITEM_SHORT_NAME = "Inspektify"
internal const val INSPEKTIFY_SHORTCUT_ITEM_LONG_NAME = "Open $INSPEKTIFY_SHORTCUT_ITEM_SHORT_NAME window"
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorClient.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorClient.kt
index 5ea0b17..19d3afa 100644
--- a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorClient.kt
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorClient.kt
@@ -25,9 +25,11 @@ internal class InspektifyKtorClient(
private val requestHandler: InspektifyRequestHandler = AppComponents.getInspektifyRequestHandler(),
private val responseHandler: InspektifyResponseHandler = AppComponents.getInspektifyResponseHandler(),
private val trafficLogger: InspektifyNetworkTrafficLogger = AppComponents.getInspektifyNetworkTrafficLogger(),
- private val dataRetentionHandler: InspektifyDataRetentionHandler = AppComponents.getInspektifyDataRetentionHandler()
+ private val dataRetentionHandler: InspektifyDataRetentionHandler =
+ AppComponents.getInspektifyDataRetentionHandler(),
+ private val ignoreEndpointHandler: InspektifyKtorIgnoreEndpointHandler =
+ AppComponents.getInspektifyKtorIgnoreEndpointHandler()
) {
-
private val coroutineScope = CoroutineScope(dispatcherProvider.main + SupervisorJob())
private var sessionId: Long? = null
@@ -47,6 +49,7 @@ internal class InspektifyKtorClient(
redactHeaders = config.redactHeaders
redactBodyProperties = config.redactBodyProperties
coroutineScope.launch(dispatcherProvider.main.immediate) {
+ ignoreEndpointHandler.configureEndpointIgnoring(config.ignoreEndpoints)
configurePresentation(config.autoDetectEnabled, config.shortcutEnabled)
dataRetentionHandler.configureDataRetentionPolicy(config.dataRetentionPolicy)
}
@@ -59,6 +62,8 @@ internal class InspektifyKtorClient(
client.sendPipeline.intercept(HttpSendPipeline.Monitoring) {
try {
+ if (ignoreEndpointHandler.shouldIgnoreEndpoint(context)) return@intercept
+
val networkTraffic = requestHandler.handleRequest(
request = context,
sessionId = sessionId,
@@ -82,15 +87,17 @@ internal class InspektifyKtorClient(
val networkTraffic = repository.getNetworkTrafficData(
response.request.attributes[requestHandler.getNetworkTrafficIdKey()]
)
- val networkTrafficWithResponse = responseHandler.handleResponse(
- response = response,
- networkTraffic = networkTraffic,
- redactHeaders = redactHeaders,
- redactBodyProperties = redactBodyProperties
- )
+ if (networkTraffic != null) {
+ val networkTrafficWithResponse = responseHandler.handleResponse(
+ response = response,
+ networkTraffic = networkTraffic,
+ redactHeaders = redactHeaders,
+ redactBodyProperties = redactBodyProperties
+ )
- repository.saveNetworkTrafficData(networkTrafficWithResponse)
- trafficLogger.logResponse(networkTrafficWithResponse)
+ repository.saveNetworkTrafficData(networkTrafficWithResponse)
+ trafficLogger.logResponse(networkTrafficWithResponse)
+ }
}
val responseObserver = ResponseObserver.prepare { onResponse(responseHandler) }
ResponseObserver.install(responseObserver, client)
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorIgnoreEndpointHandler.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorIgnoreEndpointHandler.kt
new file mode 100644
index 0000000..9a23df5
--- /dev/null
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorIgnoreEndpointHandler.kt
@@ -0,0 +1,38 @@
+package sp.bvantur.inspektify.ktor.client.data
+
+import io.ktor.client.request.HttpRequestBuilder
+import sp.bvantur.inspektify.ktor.EndpointMatchingStrategy
+import sp.bvantur.inspektify.ktor.IgnorePathData
+
+internal class InspektifyKtorIgnoreEndpointHandler {
+
+ private var ignoreEndpoints: List = emptyList()
+
+ fun configureEndpointIgnoring(ignoreEndpoints: List) {
+ this.ignoreEndpoints = ignoreEndpoints
+ }
+
+ fun shouldIgnoreEndpoint(requestBuilder: HttpRequestBuilder): Boolean = ignoreEndpoints.filter { endpoint ->
+ if (endpoint.method.isAll()) {
+ true
+ } else {
+ endpoint.method.value == requestBuilder.method.value
+ }
+ }.any { endpoint ->
+ when (endpoint.matchingStrategy) {
+ is EndpointMatchingStrategy.Contains -> {
+ val containsValue = endpoint.matchingStrategy.value
+ if (containsValue.isEmpty()) {
+ false
+ } else {
+ requestBuilder.url.toString()
+ .contains(endpoint.matchingStrategy.value)
+ }
+ }
+
+ is EndpointMatchingStrategy.Exact -> endpoint.matchingStrategy.value == requestBuilder.url.toString()
+ is EndpointMatchingStrategy.Regex -> requestBuilder.url.toString()
+ .matches(Regex(endpoint.matchingStrategy.value))
+ }
+ }
+}
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/datasource/NetworkTrafficLocalDataSource.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/datasource/NetworkTrafficLocalDataSource.kt
index daeafb2..003b366 100644
--- a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/datasource/NetworkTrafficLocalDataSource.kt
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/client/data/datasource/NetworkTrafficLocalDataSource.kt
@@ -41,10 +41,10 @@ internal class NetworkTrafficLocalDataSource(
}
}
- suspend fun getNetworkTrafficData(id: Long): NetworkTrafficDataLocal = withContext(dispatcherProvider.io) {
+ suspend fun getNetworkTrafficData(id: Long): NetworkTrafficDataLocal? = withContext(dispatcherProvider.io) {
database.inspektifyDBQueries.getNetworkTrafficById(
id
- ).executeAsOne()
+ ).executeAsOneOrNull()
}
suspend fun removeNetworkTrafficOlderThan(cutoffTimestamp: Long) {
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/data/NetworkTrafficRepositoryImpl.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/data/NetworkTrafficRepositoryImpl.kt
index 07da627..74c0494 100644
--- a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/data/NetworkTrafficRepositoryImpl.kt
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/data/NetworkTrafficRepositoryImpl.kt
@@ -12,9 +12,9 @@ internal class NetworkTrafficRepositoryImpl(private val localDataSource: Network
localDataSource.saveNetworkTrafficData(networkTraffic)
}
- override suspend fun getNetworkTrafficData(id: Long): NetworkTraffic = localDataSource.getNetworkTrafficData(
+ override suspend fun getNetworkTrafficData(id: Long): NetworkTraffic? = localDataSource.getNetworkTrafficData(
id
- ).toNetworkTraffic()
+ )?.toNetworkTraffic()
override suspend fun applyRetentionPolicyByDays(cutoffTimestamp: Long) {
localDataSource.removeNetworkTrafficOlderThan(cutoffTimestamp)
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/di/AppModule.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/di/AppModule.kt
index 9109635..d83a6e1 100644
--- a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/di/AppModule.kt
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/di/AppModule.kt
@@ -6,6 +6,7 @@ import kotlinx.serialization.json.Json
import sp.bvantur.inspektify.NetworkTrafficDataLocal
import sp.bvantur.inspektify.db.InspektifyDB
import sp.bvantur.inspektify.ktor.client.data.InspektifyDataRetentionHandler
+import sp.bvantur.inspektify.ktor.client.data.InspektifyKtorIgnoreEndpointHandler
import sp.bvantur.inspektify.ktor.client.data.InspektifyNetworkTrafficLogger
import sp.bvantur.inspektify.ktor.client.data.InspektifyRequestHandler
import sp.bvantur.inspektify.ktor.client.data.InspektifyResponseHandler
@@ -29,6 +30,7 @@ internal object AppComponents {
private var responseHandler: InspektifyResponseHandler? = null
private var trafficLogger: InspektifyNetworkTrafficLogger? = null
private var dataRetentionHandler: InspektifyDataRetentionHandler? = null
+ private var ignoreEndpointHandler: InspektifyKtorIgnoreEndpointHandler? = null
fun getDatabaseInstance(): InspektifyDB {
if (database == null) {
@@ -102,6 +104,13 @@ internal object AppComponents {
return dataRetentionHandler!!
}
+ fun getInspektifyKtorIgnoreEndpointHandler(): InspektifyKtorIgnoreEndpointHandler {
+ if (ignoreEndpointHandler == null) {
+ ignoreEndpointHandler = InspektifyKtorIgnoreEndpointHandler()
+ }
+ return ignoreEndpointHandler!!
+ }
+
private val listOfNetworkTrafficHeaderAdapter =
object : ColumnAdapter>>, String> {
override fun decode(databaseValue: String): Set>> =
diff --git a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/domain/NetworkTrafficRepository.kt b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/domain/NetworkTrafficRepository.kt
index 389f523..5933566 100644
--- a/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/domain/NetworkTrafficRepository.kt
+++ b/inspektify/src/commonMain/kotlin/sp/bvantur/inspektify/ktor/core/domain/NetworkTrafficRepository.kt
@@ -5,7 +5,7 @@ import sp.bvantur.inspektify.ktor.client.domain.model.NetworkTraffic
internal interface NetworkTrafficRepository {
suspend fun saveNetworkTrafficData(networkTraffic: NetworkTraffic)
- suspend fun getNetworkTrafficData(id: Long): NetworkTraffic
+ suspend fun getNetworkTrafficData(id: Long): NetworkTraffic?
suspend fun applyRetentionPolicyByDays(cutoffTimestamp: Long)
diff --git a/inspektify/src/commonTest/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorIgnoreEndpointHandlerTest.kt b/inspektify/src/commonTest/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorIgnoreEndpointHandlerTest.kt
new file mode 100644
index 0000000..a495324
--- /dev/null
+++ b/inspektify/src/commonTest/kotlin/sp/bvantur/inspektify/ktor/client/data/InspektifyKtorIgnoreEndpointHandlerTest.kt
@@ -0,0 +1,401 @@
+@file:Suppress("ktlint:standard:max-line-length")
+
+package sp.bvantur.inspektify.ktor.client.data
+
+import io.ktor.client.request.HttpRequestBuilder
+import io.ktor.http.HttpMethod
+import io.ktor.http.URLProtocol
+import io.ktor.http.encodedPath
+import sp.bvantur.inspektify.ktor.EndpointMatchingStrategy
+import sp.bvantur.inspektify.ktor.IgnorePathData
+import sp.bvantur.inspektify.ktor.MethodType
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+class InspektifyKtorIgnoreEndpointHandlerTest {
+
+ private lateinit var ignoreEndpointHandler: InspektifyKtorIgnoreEndpointHandler
+
+ @BeforeTest
+ fun setup() {
+ ignoreEndpointHandler = InspektifyKtorIgnoreEndpointHandler()
+ }
+
+ @Test
+ fun `GIVEN exact match strategy with correct endpoint defined and get method WHEN shouldIgnoreEndpoint is called THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/path/to/resource")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN exact match strategy with different endpoint defined and get method WHEN shouldIgnoreEndpoint is called THEN it returns that is should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ parameters.append("param1", "value1")
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/path/to/resource")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN exact match strategy with correct endpoint with params defined and post method WHEN shouldIgnoreEndpoint is called THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Post
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ parameters.append("param1", "value1")
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.POST,
+ matchingStrategy = EndpointMatchingStrategy.Exact(
+ "https://www.example.com/path/to/resource?param1=value1"
+ )
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN exact match strategy and get method WHEN shouldIgnoreEndpoint is called with post method request THEN it returns that it should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Post
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/path/to/resource")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN exact match strategy with empty value and get method WHEN shouldIgnoreEndpoint is called THEN it returns that it should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Exact("")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN contains match strategy with correct endpoint defined and get method WHEN shouldIgnoreEndpoint is called THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Contains("https://www.example.com/path/to/resource")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN contains match strategy with different endpoint defined and get method WHEN shouldIgnoreEndpoint is called THEN it returns that is should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ parameters.append("param1", "value1")
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Contains("examples")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN contains match strategy with correct endpoint with params defined and post method WHEN shouldIgnoreEndpoint is called THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Post
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ parameters.append("param1", "value1")
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.POST,
+ matchingStrategy = EndpointMatchingStrategy.Contains("resource?param1=value1")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN contains match strategy with correct endpoint defined and get method WHEN shouldIgnoreEndpoint is called on endpoint with params THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ parameters.append("param1", "value1")
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Contains("https://www.example.com/path/to/resource")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN contains match strategy with empty value and get method WHEN shouldIgnoreEndpoint is called THEN it returns that it should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Contains("")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN regex match strategy with correct regex defined and get method WHEN shouldIgnoreEndpoint is called THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Regex("https://www\\.example\\.com/.*")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN regex match strategy with correct endpoint with params defined and post method WHEN shouldIgnoreEndpoint is called THEN it returns that is should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Post
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ parameters.append("param1", "value1")
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.POST,
+ matchingStrategy = EndpointMatchingStrategy.Regex("https://www\\.example\\.com/.*")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN regex match strategy with empty value and get method WHEN shouldIgnoreEndpoint is called THEN it returns that it should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Contains("")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN multiple exact match endpoints with one of them matching passed request WHEN shouldIgnoreEndpoint is called THEN it returns that it should be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.POST,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/other/resource")
+ ),
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/path/to/resource")
+ )
+ )
+ )
+
+ assertTrue {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+
+ @Test
+ fun `GIVEN multiple exact and match endpoints with no matches WHEN shouldIgnoreEndpoint is called THEN it returns that it should not be ignored`() {
+ val request = HttpRequestBuilder().also { request ->
+ request.method = HttpMethod.Get
+ request.url {
+ protocol = URLProtocol.HTTPS
+ host = "www.example.com"
+ encodedPath = "/path/to/resource"
+ }
+ }
+ ignoreEndpointHandler.configureEndpointIgnoring(
+ listOf(
+ IgnorePathData(
+ method = MethodType.POST,
+ matchingStrategy = EndpointMatchingStrategy.Exact("https://www.example.com/other/resource")
+ ),
+ IgnorePathData(
+ method = MethodType.GET,
+ matchingStrategy = EndpointMatchingStrategy.Contains("https://www.example.com/different/resource")
+ )
+ )
+ )
+
+ assertFalse {
+ ignoreEndpointHandler.shouldIgnoreEndpoint(request)
+ }
+ }
+}
diff --git a/inspektify/src/iosMain/kotlin/sp/bvantur/inspektify/ktor/client/InspektifyShortcutHandler.kt b/inspektify/src/iosMain/kotlin/sp/bvantur/inspektify/ktor/client/InspektifyShortcutHandler.kt
index df84d98..ab7c9d3 100644
--- a/inspektify/src/iosMain/kotlin/sp/bvantur/inspektify/ktor/client/InspektifyShortcutHandler.kt
+++ b/inspektify/src/iosMain/kotlin/sp/bvantur/inspektify/ktor/client/InspektifyShortcutHandler.kt
@@ -38,7 +38,9 @@ internal class InspektifySceneDelegate @OverrideInit constructor() :
}
@OptIn(BetaInteropApi::class)
-fun getInspektifyUISceneConfiguration(configurationForConnectingSceneSession: UISceneSession): UISceneConfiguration {
+public fun getInspektifyUISceneConfiguration(
+ configurationForConnectingSceneSession: UISceneSession
+): UISceneConfiguration {
val configuration = UISceneConfiguration(
name = configurationForConnectingSceneSession.configuration.name,
sessionRole = configurationForConnectingSceneSession.role
@@ -48,4 +50,4 @@ fun getInspektifyUISceneConfiguration(configurationForConnectingSceneSession: UI
}
@Suppress("FunctionOnlyReturningConstant")
-fun getInspektifyShortcutType(): String = "Inspektify"
+public fun getInspektifyShortcutType(): String = "Inspektify"
diff --git a/inspektifySample/composeApp/src/commonMain/kotlin/sp/bvantur/inspektify/sample/di/NetworkModule.kt b/inspektifySample/composeApp/src/commonMain/kotlin/sp/bvantur/inspektify/sample/di/NetworkModule.kt
index 37639f5..afe879c 100644
--- a/inspektifySample/composeApp/src/commonMain/kotlin/sp/bvantur/inspektify/sample/di/NetworkModule.kt
+++ b/inspektifySample/composeApp/src/commonMain/kotlin/sp/bvantur/inspektify/sample/di/NetworkModule.kt
@@ -32,6 +32,12 @@ val networkModule = module {
autoDetectEnabled = false
logLevel = LogLevel.All
dataRetentionPolicy = DataRetentionPolicy.SessionCount(4)
+// ignoreEndpoints = listOf(
+// IgnorePathData(
+// method = MethodType.ALL,
+// matchingStrategy = EndpointMatchingStrategy.Regex("https://reqres\\.in/.*"),
+// )
+// )
}
}
}
diff --git a/konsistTest/src/jvmTest/kotlin/inspektify/LibKonsistTest.kt b/konsistTest/src/jvmTest/kotlin/inspektify/LibKonsistTest.kt
index af37951..004df45 100644
--- a/konsistTest/src/jvmTest/kotlin/inspektify/LibKonsistTest.kt
+++ b/konsistTest/src/jvmTest/kotlin/inspektify/LibKonsistTest.kt
@@ -32,7 +32,10 @@ class LibKonsistTest {
val allowedPublicComponents = listOf(
"InspektifyKtor",
"InspektifyKtorConfig",
- "NetworkTrafficHeader"
+ "NetworkTrafficHeader",
+ "IgnorePathData",
+ "MethodType",
+ "EndpointMatchingStrategy"
)
Konsist.scopeFromModule("inspektify")
@@ -93,7 +96,10 @@ class LibKonsistTest {
"InspektifyKtorConfig:autoDetectEnabled",
"InspektifyKtorConfig:shortcutEnabled",
"InspektifyKtorConfig:redactHeaders",
- "InspektifyKtorConfig:redactBodyProperties"
+ "InspektifyKtorConfig:redactBodyProperties",
+ "InspektifyKtorConfig:ignoreEndpoints",
+ "IgnorePathData:method",
+ "IgnorePathData:matchingStrategy"
)
val publicComponents = mutableListOf()