/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.controls.management import android.app.PendingIntent import android.content.ComponentName import android.service.controls.Control import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlStatus import com.android.systemui.controls.controller.ControlInfo import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidJUnit4::class) class AllModelTest : SysuiTestCase() { companion object { private const val EMPTY_STRING = "Other" } @Mock lateinit var pendingIntent: PendingIntent @Mock lateinit var controlsModelCallback: ControlsModel.ControlsModelCallback val idPrefix = "controlId" val favoritesIndices = listOf(7, 3, 1, 9) val favoritesList = favoritesIndices.map { "controlId$it" } lateinit var controls: List lateinit var model: AllModel private fun zoneMap(id: Int): String? { return when (id) { 10 -> "" 11 -> null else -> ((id + 1) % 3).toString() } } @Before fun setUp() { MockitoAnnotations.initMocks(this) // controlId0 --> zone = 1 // controlId1 --> zone = 2, favorite // controlId2 --> zone = 0 // controlId3 --> zone = 1, favorite // controlId4 --> zone = 2 // controlId5 --> zone = 0 // controlId6 --> zone = 1 // controlId7 --> zone = 2, favorite // controlId8 --> zone = 0 // controlId9 --> zone = 1, favorite // controlId10 --> zone = "" // controlId11 --> zone = null controls = (0..11).map { ControlStatus( Control.StatelessBuilder("$idPrefix$it", pendingIntent) .setZone(zoneMap(it)) .build(), ComponentName("", ""), it in favoritesIndices ) } model = AllModel(controls, favoritesList, EMPTY_STRING, controlsModelCallback) } @Test fun testElements() { // Zones are sorted by order of appearance, with empty at the end with special header. val expected = listOf( ZoneNameWrapper("1"), ControlStatusWrapper(controls[0]), ControlStatusWrapper(controls[3]), ControlStatusWrapper(controls[6]), ControlStatusWrapper(controls[9]), ZoneNameWrapper("2"), ControlStatusWrapper(controls[1]), ControlStatusWrapper(controls[4]), ControlStatusWrapper(controls[7]), ZoneNameWrapper("0"), ControlStatusWrapper(controls[2]), ControlStatusWrapper(controls[5]), ControlStatusWrapper(controls[8]), ZoneNameWrapper(EMPTY_STRING), ControlStatusWrapper(controls[10]), ControlStatusWrapper(controls[11]) ) expected.zip(model.elements).forEachIndexed { index, it -> assertEquals("Error in item at index $index", it.first, it.second) } } private fun sameControl(controlInfo: ControlInfo, control: Control): Boolean { return controlInfo.controlId == control.controlId && controlInfo.controlTitle == control.title && controlInfo.controlSubtitle == control.subtitle && controlInfo.deviceType == control.deviceType } @Test fun testAllEmpty_noHeader() { val selected_controls = listOf(controls[10], controls[11]) val new_model = AllModel(selected_controls, emptyList(), EMPTY_STRING, controlsModelCallback) val expected = listOf( ControlStatusWrapper(controls[10]), ControlStatusWrapper(controls[11]) ) expected.zip(new_model.elements).forEachIndexed { index, it -> assertEquals("Error in item at index $index", it.first, it.second) } } @Test fun testFavorites() { val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control) model.favorites.zip(expectedFavorites).forEach { assertTrue(sameControl(it.first, it.second)) } } @Test fun testAddFavorite() { val indexToAdd = 6 model.changeFavoriteStatus("$idPrefix$indexToAdd", true) val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control) + controls[indexToAdd].control model.favorites.zip(expectedFavorites).forEach { assertTrue(sameControl(it.first, it.second)) } verify(controlsModelCallback).onFirstChange() verify(controlsModelCallback).onChange() } @Test fun testAddFavorite_changesModelFlag() { val indexToAdd = 6 val id = "$idPrefix$indexToAdd" model.changeFavoriteStatus(id, true) assertTrue( (model.elements.first { it is ControlStatusWrapper && it.controlStatus.control.controlId == id } as ControlStatusWrapper) .controlStatus.favorite ) verify(controlsModelCallback).onFirstChange() verify(controlsModelCallback).onChange() } @Test fun testAddFavorite_alreadyThere() { val indexToAdd = 7 model.changeFavoriteStatus("$idPrefix$indexToAdd", true) val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control) assertEquals(expectedFavorites.size, model.favorites.size) model.favorites.zip(expectedFavorites).forEach { assertTrue(sameControl(it.first, it.second)) } verify(controlsModelCallback, never()).onFirstChange() verify(controlsModelCallback, never()).onChange() } @Test fun testRemoveFavorite() { val indexToRemove = 3 model.changeFavoriteStatus("$idPrefix$indexToRemove", false) val expectedFavorites = (favoritesIndices.filterNot { it == indexToRemove }) .map(controls::get) .map(ControlStatus::control) model.favorites.zip(expectedFavorites).forEach { assertTrue(sameControl(it.first, it.second)) } verify(controlsModelCallback).onFirstChange() verify(controlsModelCallback).onChange() } @Test fun testRemoveFavorite_changesModelFlag() { val indexToRemove = 3 val id = "$idPrefix$indexToRemove" model.changeFavoriteStatus(id, false) assertFalse( (model.elements.first { it is ControlStatusWrapper && it.controlStatus.control.controlId == id } as ControlStatusWrapper) .controlStatus.favorite ) verify(controlsModelCallback).onFirstChange() verify(controlsModelCallback).onChange() } @Test fun testRemoveFavorite_notThere() { val indexToRemove = 4 model.changeFavoriteStatus("$idPrefix$indexToRemove", false) val expectedFavorites = favoritesIndices.map(controls::get).map(ControlStatus::control) model.favorites.zip(expectedFavorites).forEach { assertTrue(sameControl(it.first, it.second)) } verify(controlsModelCallback, never()).onFirstChange() verify(controlsModelCallback, never()).onChange() } @Test fun testAddSecondChange_callbacks() { model.changeFavoriteStatus("${idPrefix}4", true) model.changeFavoriteStatus("${idPrefix}5", true) verify(controlsModelCallback).onFirstChange() verify(controlsModelCallback, times(2)).onChange() } @Test fun testRemoveSecondChange_callbacks() { model.changeFavoriteStatus("${idPrefix}1", false) model.changeFavoriteStatus("${idPrefix}3", false) verify(controlsModelCallback).onFirstChange() verify(controlsModelCallback, times(2)).onChange() } }