1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.jetpackcamera.feature.preview.ui
17 
18 import androidx.compose.runtime.MutableState
19 import androidx.compose.runtime.mutableStateOf
20 import androidx.compose.ui.graphics.Color
21 import androidx.compose.ui.graphics.toArgb
22 import androidx.compose.ui.test.assertHeightIsAtLeast
23 import androidx.compose.ui.test.assertWidthIsAtLeast
24 import androidx.compose.ui.test.captureToImage
25 import androidx.compose.ui.test.getBoundsInRoot
26 import androidx.compose.ui.test.hasTestTag
27 import androidx.compose.ui.test.junit4.createComposeRule
28 import androidx.compose.ui.test.onRoot
29 import androidx.compose.ui.unit.height
30 import androidx.compose.ui.unit.width
31 import androidx.test.ext.junit.runners.AndroidJUnit4
32 import com.google.jetpackcamera.feature.preview.ScreenFlash
33 import kotlinx.coroutines.test.runTest
34 import org.junit.Assert.assertEquals
35 import org.junit.Before
36 import org.junit.Rule
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 
40 @RunWith(AndroidJUnit4::class)
41 class ScreenFlashComponentsKtTest {
42     @get:Rule
43     val composeTestRule = createComposeRule()
44 
45     private val screenFlashUiState: MutableState<ScreenFlash.ScreenFlashUiState> =
46         mutableStateOf(ScreenFlash.ScreenFlashUiState())
47 
48     @Before
setUpnull49     fun setUp() {
50         composeTestRule.setContent {
51             ScreenFlashScreen(
52                 screenFlashUiState = screenFlashUiState.value,
53                 onInitialBrightnessCalculated = {}
54             )
55         }
56     }
57 
58     @Test
<lambda>null59     fun screenFlashOverlay_doesNotExistByDefault() = runTest {
60         composeTestRule.awaitIdle()
61         composeTestRule.onNode(hasTestTag("ScreenFlashOverlay")).assertDoesNotExist()
62     }
63 
64     @Test
<lambda>null65     fun screenFlashOverlay_existsAfterStateIsEnabled() = runTest {
66         screenFlashUiState.value = ScreenFlash.ScreenFlashUiState(enabled = true)
67 
68         composeTestRule.awaitIdle()
69         composeTestRule.onNode(hasTestTag("ScreenFlashOverlay")).assertExists()
70     }
71 
72     @Test
<lambda>null73     fun screenFlashOverlay_doesNotExistWhenDisabledAfterEnabled() = runTest {
74         screenFlashUiState.value = ScreenFlash.ScreenFlashUiState(enabled = true)
75         screenFlashUiState.value = ScreenFlash.ScreenFlashUiState(enabled = false)
76 
77         composeTestRule.awaitIdle()
78         composeTestRule.onNode(hasTestTag("ScreenFlashOverlay")).assertDoesNotExist()
79     }
80 
81     @Test
<lambda>null82     fun screenFlashOverlay_sizeFillsMaxSize() = runTest {
83         screenFlashUiState.value = ScreenFlash.ScreenFlashUiState(enabled = true)
84 
85         composeTestRule.awaitIdle()
86         val rootBounds = composeTestRule.onRoot().getBoundsInRoot()
87         composeTestRule.onNode(hasTestTag("ScreenFlashOverlay"))
88             .assertWidthIsAtLeast(rootBounds.width)
89         composeTestRule.onNode(hasTestTag("ScreenFlashOverlay"))
90             .assertHeightIsAtLeast(rootBounds.height)
91     }
92 
93     @Test
<lambda>null94     fun screenFlashOverlay_fullWhiteWhenEnabled() = runTest {
95         screenFlashUiState.value = ScreenFlash.ScreenFlashUiState(enabled = true)
96 
97         composeTestRule.awaitIdle()
98         val overlayScreenShot =
99             composeTestRule.onNode(hasTestTag("ScreenFlashOverlay")).captureToImage()
100 
101         // check a few pixels near center instead of whole image to save time
102         val overlayPixels = IntArray(4)
103         overlayScreenShot.readPixels(
104             overlayPixels,
105             overlayScreenShot.width / 2,
106             overlayScreenShot.height / 2,
107             2,
108             2
109         )
110         overlayPixels.forEach {
111             assertEquals(Color.White.toArgb(), it)
112         }
113     }
114 }
115