View test reports →

Coverage Summary for Class: HttpLogPagingSource (dev.skymansandy.wiretap.data.repository)

Class Method, % Branch, % Line, % Instruction, %
HttpLogPagingSource 0% (0/4) 0% (0/8) 0% (0/37) 0% (0/265)
HttpLogPagingSource$1 0% (0/1) 0% (0/1) 0% (0/22)
HttpLogPagingSource$1$1 0% (0/1) 0% (0/1) 0% (0/3)
HttpLogPagingSource$load$1
Total 0% (0/6) 0% (0/8) 0% (0/39) 0% (0/290)


 /*
  * Copyright (c) 2026 skymansandy. All rights reserved.
  */
 
 package dev.skymansandy.wiretap.data.repository
 
 import androidx.paging.PagingConfig
 import androidx.paging.PagingSource
 import androidx.paging.PagingSource.LoadParams
 import androidx.paging.PagingSource.LoadResult
 import androidx.paging.PagingState
 import dev.skymansandy.wiretap.data.db.room.dao.HttpLogsDao
 import dev.skymansandy.wiretap.data.mappers.toDomain
 import dev.skymansandy.wiretap.domain.model.HttpLog
 import dev.skymansandy.wiretap.domain.model.HttpLogFilter
 import dev.skymansandy.wiretap.domain.model.StatusGroup
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.launch
 
 private const val PAGE_SIZE = 20
 internal val defaultPagingConfig = PagingConfig(
     pageSize = PAGE_SIZE,
     prefetchDistance = 3 * PAGE_SIZE,
     enablePlaceholders = false,
 )
 
 internal class HttpLogPagingSource(
     private val roomDao: HttpLogsDao,
     private val query: String,
     private val filter: HttpLogFilter,
     invalidationSignal: SharedFlow<Unit>,
 ) : PagingSource<Long, HttpLog>() {
 
     private val listenerScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
 
     init {
         listenerScope.launch {
             invalidationSignal.collect {
                 invalidate()
             }
         }
 
         registerInvalidatedCallback {
             listenerScope.cancel()
         }
     }
 
     override suspend fun load(params: LoadParams<Long>): LoadResult<Long, HttpLog> {
         val afterId = params.key
         return try {
             val statusGroups = filter.statusGroups
             val items = roomDao.getPage(
                 query = query,
                 noStatusFilter = if (statusGroups.isEmpty()) 1 else 0,
                 hasInProgress = if (StatusGroup.InProgress in statusGroups) 1 else 0,
                 hasSuccess = if (StatusGroup.Success in statusGroups) 1 else 0,
                 hasRedirect = if (StatusGroup.Redirect in statusGroups) 1 else 0,
                 hasClientError = if (StatusGroup.ClientError in statusGroups) 1 else 0,
                 hasServerError = if (StatusGroup.ServerError in statusGroups) 1 else 0,
                 hasFailed = if (StatusGroup.Failed in statusGroups) 1 else 0,
                 noMethodFilter = if (filter.methods.isEmpty()) 1 else 0,
                 methods = filter.methods.toList().ifEmpty { listOf("") },
                 noSourceFilter = if (filter.sources.isEmpty()) 1 else 0,
                 sources = filter.sources.map { it.name }.ifEmpty { listOf("") },
                 noDomainFilter = if (filter.domains.isEmpty()) 1 else 0,
                 domains = filter.domains.toList().ifEmpty { listOf("") },
                 afterId = afterId,
                 limit = params.loadSize.toLong(),
             ).map {
                 it.toDomain()
             }
 
             LoadResult.Page(
                 data = items,
                 prevKey = null, // newest-first; no back-paging needed
                 nextKey = if (items.size < params.loadSize) null else items.last().id,
             )
         } catch (e: Exception) {
             LoadResult.Error(e)
         }
     }
 
     override fun getRefreshKey(state: PagingState<Long, HttpLog>): Long? = null
 }