• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.systemui.qs.panels.ui.compose
18 
19 import androidx.compose.ui.text.AnnotatedString
20 import androidx.test.ext.junit.runners.AndroidJUnit4
21 import androidx.test.filters.SmallTest
22 import com.android.systemui.SysuiTestCase
23 import com.android.systemui.common.shared.model.Icon
24 import com.android.systemui.qs.panels.shared.model.SizedTile
25 import com.android.systemui.qs.panels.shared.model.SizedTileImpl
26 import com.android.systemui.qs.panels.ui.compose.selection.PlacementEvent
27 import com.android.systemui.qs.panels.ui.model.GridCell
28 import com.android.systemui.qs.panels.ui.model.TileGridCell
29 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
30 import com.android.systemui.qs.pipeline.shared.TileSpec
31 import com.android.systemui.qs.shared.model.TileCategory
32 import com.google.common.truth.Truth.assertThat
33 import org.junit.Test
34 import org.junit.runner.RunWith
35 
36 @SmallTest
37 @RunWith(AndroidJUnit4::class)
38 class EditTileListStateTest : SysuiTestCase() {
39     private val underTest = EditTileListState(TestEditTiles, columns = 4, largeTilesSpan = 2)
40 
41     @Test
startDrag_listHasSpacersnull42     fun startDrag_listHasSpacers() {
43         underTest.onStarted(TestEditTiles[0], DragType.Add)
44 
45         // [ a ] [ b ] [ c ] [ X ]
46         // [ Large D ] [ e ] [ X ]
47         assertThat(underTest.tiles.toStrings())
48             .isEqualTo(listOf("a", "b", "c", "spacer", "d", "e", "spacer"))
49         assertThat(underTest.isMoving(TestEditTiles[0].tile.tileSpec)).isTrue()
50         assertThat(underTest.dragInProgress).isTrue()
51     }
52 
53     @Test
moveDrag_listChangesnull54     fun moveDrag_listChanges() {
55         underTest.onStarted(TestEditTiles[4], DragType.Add)
56         underTest.onTargeting(3, false)
57 
58         // Tile E goes to index 3
59         // [ a ] [ b ] [ c ] [ e ]
60         // [ Large D ] [ X ] [ X ]
61         assertThat(underTest.tiles.toStrings())
62             .isEqualTo(listOf("a", "b", "c", "e", "d", "spacer", "spacer"))
63     }
64 
65     @Test
moveDragOnSidesOfLargeTile_listChangesnull66     fun moveDragOnSidesOfLargeTile_listChanges() {
67         val draggedCell = TestEditTiles[4]
68 
69         underTest.onStarted(draggedCell, DragType.Add)
70         underTest.onTargeting(4, true)
71 
72         // Tile E goes to the right side of tile D, list is unchanged
73         // [ a ] [ b ] [ c ] [ X ]
74         // [ Large D ] [ e ] [ X ]
75         assertThat(underTest.tiles.toStrings())
76             .isEqualTo(listOf("a", "b", "c", "spacer", "d", "e", "spacer"))
77 
78         underTest.onTargeting(4, false)
79 
80         // Tile E goes to the left side of tile D, they swap positions
81         // [ a ] [ b ] [ c ] [ e ]
82         // [ Large D ] [ X ] [ X ]
83         assertThat(underTest.tiles.toStrings())
84             .isEqualTo(listOf("a", "b", "c", "e", "d", "spacer", "spacer"))
85     }
86 
87     @Test
moveNewTile_tileIsAddednull88     fun moveNewTile_tileIsAdded() {
89         val newTile = createEditTile("newTile", 2)
90 
91         underTest.onStarted(newTile, DragType.Add)
92         underTest.onTargeting(5, false)
93 
94         // New tile goes to index 5
95         // [ a ] [ b ] [ c ] [ X ]
96         // [ Large D ] [ newTile ]
97         // [ e ] [ X ] [ X ] [ X ]
98         assertThat(underTest.tiles.toStrings())
99             .isEqualTo(
100                 listOf("a", "b", "c", "spacer", "d", "newTile", "e", "spacer", "spacer", "spacer")
101             )
102     }
103 
104     @Test
movedTileOutOfBounds_tileDisappearsnull105     fun movedTileOutOfBounds_tileDisappears() {
106         underTest.onStarted(TestEditTiles[0], DragType.Add)
107         underTest.movedOutOfBounds()
108 
109         assertThat(underTest.tiles.toStrings()).doesNotContain(TestEditTiles[0].tile.tileSpec.spec)
110     }
111 
112     @Test
targetIndexForPlacementToTileSpec_returnsCorrectIndexnull113     fun targetIndexForPlacementToTileSpec_returnsCorrectIndex() {
114         val placementEvent =
115             PlacementEvent.PlaceToTileSpec(
116                 movingSpec = TestEditTiles[0].tile.tileSpec,
117                 targetSpec = TestEditTiles[3].tile.tileSpec,
118             )
119         val index = underTest.targetIndexForPlacement(placementEvent)
120 
121         assertThat(index).isEqualTo(3)
122     }
123 
124     @Test
targetIndexForPlacementToIndex_indexOutOfBounds_returnsCorrectIndexnull125     fun targetIndexForPlacementToIndex_indexOutOfBounds_returnsCorrectIndex() {
126         val placementEventTooLow =
127             PlacementEvent.PlaceToIndex(
128                 movingSpec = TestEditTiles[0].tile.tileSpec,
129                 targetIndex = -1,
130             )
131         val index1 = underTest.targetIndexForPlacement(placementEventTooLow)
132 
133         assertThat(index1).isEqualTo(0)
134 
135         val placementEventTooHigh =
136             PlacementEvent.PlaceToIndex(
137                 movingSpec = TestEditTiles[0].tile.tileSpec,
138                 targetIndex = 10,
139             )
140         val index2 = underTest.targetIndexForPlacement(placementEventTooHigh)
141         assertThat(index2).isEqualTo(TestEditTiles.size)
142     }
143 
144     @Test
targetIndexForPlacementToIndex_movingBack_returnsCorrectIndexnull145     fun targetIndexForPlacementToIndex_movingBack_returnsCorrectIndex() {
146         /**
147          * With the grid: [ a ] [ b ] [ c ] [ Large D ] [ e ] [ f ]
148          *
149          * Moving 'e' to the spacer at index 3 will result in the tilespec order: a, b, c, e, d, f
150          *
151          * 'e' is now at index 3
152          */
153         val placementEvent =
154             PlacementEvent.PlaceToIndex(
155                 movingSpec = TestEditTiles[4].tile.tileSpec,
156                 targetIndex = 3,
157             )
158         val index = underTest.targetIndexForPlacement(placementEvent)
159 
160         assertThat(index).isEqualTo(3)
161     }
162 
163     @Test
targetIndexForPlacementToIndex_movingForward_returnsCorrectIndexnull164     fun targetIndexForPlacementToIndex_movingForward_returnsCorrectIndex() {
165         /**
166          * With the grid: [ a ] [ b ] [ c ] [ Large D ] [ e ] [ f ]
167          *
168          * Moving '1' to the spacer at index 3 will result in the tilespec order: b, c, a, d, e, f
169          *
170          * 'a' is now at index 2
171          */
172         val placementEvent =
173             PlacementEvent.PlaceToIndex(
174                 movingSpec = TestEditTiles[0].tile.tileSpec,
175                 targetIndex = 3,
176             )
177         val index = underTest.targetIndexForPlacement(placementEvent)
178 
179         assertThat(index).isEqualTo(2)
180     }
181 
toStringsnull182     private fun List<GridCell>.toStrings(): List<String> {
183         return map {
184             if (it is TileGridCell) {
185                 it.tile.tileSpec.spec
186             } else {
187                 "spacer"
188             }
189         }
190     }
191 
192     companion object {
createEditTilenull193         private fun createEditTile(tileSpec: String, width: Int): SizedTile<EditTileViewModel> {
194             return SizedTileImpl(
195                 EditTileViewModel(
196                     tileSpec = TileSpec.create(tileSpec),
197                     icon = Icon.Resource(0, null),
198                     label = AnnotatedString("unused"),
199                     appName = null,
200                     isCurrent = true,
201                     availableEditActions = emptySet(),
202                     category = TileCategory.UNKNOWN,
203                 ),
204                 width,
205             )
206         }
207 
208         // [ a ] [ b ] [ c ]
209         // [ Large D ] [ e ] [ f ]
210         private val TestEditTiles =
211             listOf(
212                 createEditTile("a", 1),
213                 createEditTile("b", 1),
214                 createEditTile("c", 1),
215                 createEditTile("d", 2),
216                 createEditTile("e", 1),
217             )
218     }
219 }
220