Coverage Summary for Class: SurferErrorBoundaryKt (com.georgeci.moneysurfer.uikit.components)

Class Class, % Method, % Branch, % Line, % Instruction, %
SurferErrorBoundaryKt 100% (1/1) 66.7% (2/3) 41.7% (5/12) 100% (21/21) 95.8% (183/191)


 package com.georgeci.moneysurfer.uikit.components
 
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material3.Surface
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.tooling.preview.Preview
 import com.georgeci.moneysurfer.uikit.preview.SurferComponentPreview
 import com.georgeci.moneysurfer.uikit.theme.AppTheme
 import moneysurfer.uikit.generated.resources.Res
 import moneysurfer.uikit.generated.resources.uikit_error_boundary_subtitle
 import moneysurfer.uikit.generated.resources.uikit_error_boundary_title
 import moneysurfer.uikit.generated.resources.uikit_retry
 import org.jetbrains.compose.resources.stringResource
 
 /**
  * App-level fallback for failures no screen handled itself: while [hasError] is true a
  * full-bleed [SurferErrorState] with a retry action covers [content] (issue #78).
  *
  * The content stays composed underneath rather than being torn down and rebuilt, so a
  * transient failure does not cost the user their navigation back stack — dismissing via
  * [onRetry] returns them exactly where they were, and the screen's own reload runs on the
  * data it already observes.
  */
 @Composable
 fun SurferErrorBoundary(
     hasError: Boolean,
     onRetry: () -> Unit,
     modifier: Modifier = Modifier,
     content: @Composable () -> Unit,
 ) {
     Box(modifier = modifier.fillMaxSize()) {
         content()
 
         if (hasError) {
             Surface(
                 modifier = Modifier
                     .fillMaxSize()
                     .testTag(SurferErrorBoundaryTestTags.Fallback),
                 color = AppTheme.materialColors.surface,
             ) {
                 Box(contentAlignment = Alignment.Center) {
                     SurferErrorState(
                         title = stringResource(Res.string.uikit_error_boundary_title),
                         subtitle = stringResource(Res.string.uikit_error_boundary_subtitle),
                         retryLabel = stringResource(Res.string.uikit_retry),
                         onRetry = onRetry,
                     )
                 }
             }
         }
     }
 }
 
 object SurferErrorBoundaryTestTags {
     const val Fallback = "errorBoundary:fallback"
 }
 
 @Preview
 @Composable
 private fun SurferErrorBoundaryPreview() {
     SurferComponentPreview {
         SurferErrorBoundary(hasError = true, onRetry = {}) {}
     }
 }