Coverage Summary for Class: DeleteTransactionWithUndo (com.georgeci.moneysurfer.navigation)

Class Method, % Branch, % Line, % Instruction, %
DeleteTransactionWithUndo 100% (2/2) 100% (2/2) 100% (9/9) 100% (51/51)
DeleteTransactionWithUndo$invoke$1
DeleteTransactionWithUndo$invoke$2 100% (1/1) 100% (1/1) 100% (25/25)
Total 100% (3/3) 100% (2/2) 100% (10/10) 100% (76/76)


 package com.georgeci.moneysurfer.navigation
 
 import com.georgeci.moneysurfer.domain.primitives.TransactionId
 import com.georgeci.moneysurfer.domain.usecase.DeleteTransactionUseCase
 import com.georgeci.moneysurfer.domain.usecase.RestoreTransactionsUseCase
 import org.jetbrains.compose.resources.StringResource
 import org.koin.core.annotation.Single
 
 /**
  * Deletes a transaction and offers it back through the app-level snackbar.
  *
  * Three lists can now delete a row by swiping it — transactions, an account's history, a
  * category's history — and the delete is only half the interaction: without the Undo beside it a
  * gesture that destroys data on a single sideways drag is not one users can afford to make. Both
  * halves live here so the three ViewModels cannot drift into three different answers about what
  * a swipe destroys or how long the way back stays open.
  *
  * The Undo runs on [SnackbarController]'s app-scoped coroutine, so it still works after the user
  * navigates away from the list that produced the message.
  *
  * Each caller passes its own [message] and [undoLabel] because the wording belongs to the screen,
  * not to the delete.
  */
 @Single
 class DeleteTransactionWithUndo(
     private val deleteTransaction: DeleteTransactionUseCase,
     private val restoreTransactions: RestoreTransactionsUseCase,
     private val snackbar: SnackbarController,
 ) {
 
     suspend operator fun invoke(
         transactionId: TransactionId,
         message: StringResource,
         undoLabel: StringResource,
     ) {
         // Both legs of a transfer, when that is what was swiped — see DeleteTransactionUseCase.
         val deleted = deleteTransaction(transactionId)
         // Nothing was removed (the row is already gone), so there is nothing to undo and a
         // "Deleted" message would be a lie.
         if (deleted.isEmpty()) return
         snackbar.show(
             message = message,
             actionLabel = undoLabel,
             onAction = { restoreTransactions(deleted) },
         )
     }
 }