View test reports →

Coverage Summary for Class: SocketLogManagerImpl (dev.skymansandy.wiretap.domain.orchestrator)

Class Method, % Branch, % Line, % Instruction, %
SocketLogManagerImpl 100% (10/10) 87.5% (7/8) 100% (32/32) 100% (273/273)
SocketLogManagerImpl$clearLogs$1
SocketLogManagerImpl$createSocket$1
SocketLogManagerImpl$logSocketMsg$1
SocketLogManagerImpl$updateSocket$1
SocketLogManagerImpl$WhenMappings
Total 100% (10/10) 87.5% (7/8) 100% (32/32) 100% (273/273)


 /*
  * Copyright (c) 2026 skymansandy. All rights reserved.
  */
 
 package dev.skymansandy.wiretap.domain.orchestrator
 
 import androidx.paging.PagingData
 import co.touchlab.stately.collections.ConcurrentMutableMap
 import dev.skymansandy.wiretap.domain.model.SocketConnection
 import dev.skymansandy.wiretap.domain.model.SocketMessage
 import dev.skymansandy.wiretap.domain.model.SocketStatus
 import dev.skymansandy.wiretap.domain.repository.SocketRepository
 import dev.skymansandy.wiretap.helper.launcher.WiretapNotificationHook
 import kotlinx.coroutines.flow.Flow
 
 internal class SocketLogManagerImpl(
     private val socketRepository: SocketRepository,
     private val notificationHook: WiretapNotificationHook,
 ) : SocketLogManager {
 
     // Cache of active (OPEN/CONNECTING) socket connections, used to re-create entries after log clear
     private val activeConnections = ConcurrentMutableMap<Long, SocketConnection>()
 
     override suspend fun createSocket(entry: SocketConnection): Long {
         val id = socketRepository.logNew(entry)
         val entryWithId = entry.copy(id = id)
         activeConnections[id] = entryWithId
         notificationHook.onNewSocketConnection(entryWithId)
         return id
     }
 
     override suspend fun updateSocket(entry: SocketConnection) {
         socketRepository.update(entry)
         when (entry.status) {
             SocketStatus.Closed,
             SocketStatus.Failed,
             -> activeConnections.remove(entry.id)
 
             else -> activeConnections[entry.id] = entry
         }
         notificationHook.onNewSocketConnection(entry)
     }
 
     override suspend fun logSocketMsg(message: SocketMessage) {
         // If the socket entry was cleared but the connection is still active, re-create it
         val existingEntry = socketRepository.getById(message.socketId)
         if (existingEntry == null) {
             val cached = activeConnections[message.socketId]
             if (cached != null) {
                 val reopened = cached.copy(historyCleared = true, messageCount = 0)
                 socketRepository.markReopened(reopened)
                 notificationHook.onNewSocketConnection(reopened)
             }
         }
 
         socketRepository.logSocketMsg(message)
         socketRepository.getById(message.socketId)?.let { entry ->
             notificationHook.onNewSocketMessage(entry, message)
         }
     }
 
     override suspend fun getSocketById(id: Long): SocketConnection? = socketRepository.getById(id)
 
     override fun flowSocketById(id: Long): Flow<SocketConnection?> = socketRepository.flowById(id)
 
     override fun flowSocketMessagesById(socketId: Long): Flow<List<SocketMessage>> =
         socketRepository.flowMessagesForId(socketId)
 
     override fun flowAllSockets(): Flow<List<SocketConnection>> = socketRepository.flowAll()
 
     override fun flowPagedSocketsForSearchQuery(query: String): Flow<PagingData<SocketConnection>> =
         socketRepository.flowForSearchQuery(query)
 
     override suspend fun clearLogs() {
         socketRepository.clearAll()
         notificationHook.onClearSocketLogs()
     }
 }