blob: 034549dec0bce7929b81a8658d55bae904b463c3 [file] [log] [blame]
/*
* Copyright (C) 2021 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 android.safetycenter.cts
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION_CODES.TIRAMISU
import android.safetycenter.SafetySourceData
import android.safetycenter.SafetySourceData.SEVERITY_LEVEL_CRITICAL_WARNING
import android.safetycenter.SafetySourceData.SEVERITY_LEVEL_INFORMATION
import android.safetycenter.SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION
import android.safetycenter.SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED
import android.safetycenter.SafetySourceIssue
import android.safetycenter.SafetySourceStatus
import android.safetycenter.cts.testing.EqualsHashCodeToStringTester
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.truth.os.ParcelableSubject.assertThat
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertFailsWith
import org.junit.Test
import org.junit.runner.RunWith
/** CTS tests for [SafetySourceData]. */
@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = TIRAMISU, codeName = "Tiramisu")
class SafetySourceDataTest {
private val context: Context = getApplicationContext()
@Test
fun getStatus_withDefaultBuilder_returnsNull() {
val safetySourceData =
SafetySourceData.Builder().addIssue(createIssue(SEVERITY_LEVEL_INFORMATION)).build()
assertThat(safetySourceData.status).isNull()
}
@Test
fun getStatus_whenSetExplicitly_returnsStatus() {
val status = createStatus(SEVERITY_LEVEL_INFORMATION)
val safetySourceData = SafetySourceData.Builder().setStatus(status).build()
assertThat(safetySourceData.status).isEqualTo(status)
}
@Test
fun getIssues_withDefaultBuilder_returnsEmptyList() {
val safetySourceData =
SafetySourceData.Builder().setStatus(createStatus(SEVERITY_LEVEL_INFORMATION)).build()
assertThat(safetySourceData.issues).isEmpty()
}
@Test
fun getIssues_whenSetExplicitly_returnsIssues() {
val firstIssue = createIssue(SEVERITY_LEVEL_INFORMATION, 1)
val secondIssue = createIssue(SEVERITY_LEVEL_INFORMATION, 2)
val safetySourceData =
SafetySourceData.Builder().addIssue(firstIssue).addIssue(secondIssue).build()
assertThat(safetySourceData.issues).containsExactly(firstIssue, secondIssue).inOrder()
}
@Test
fun clearIssues_removesAllIssues() {
val firstIssue = createIssue(SEVERITY_LEVEL_INFORMATION, 1)
val secondIssue = createIssue(SEVERITY_LEVEL_INFORMATION, 2)
val safetySourceData =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_INFORMATION))
.addIssue(firstIssue)
.addIssue(secondIssue)
.clearIssues()
.build()
assertThat(safetySourceData.issues).isEmpty()
}
@Test
fun build_withNoStatusAndNoIssues_doesNotThrow() {
val builder = SafetySourceData.Builder()
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withNoStatusAndInfoIssues_doesNotThrow() {
val builder = SafetySourceData.Builder().addIssue(createIssue(SEVERITY_LEVEL_INFORMATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withNoStatusAndRecommendationIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder().addIssue(createIssue(SEVERITY_LEVEL_RECOMMENDATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withNoStatusAndCriticalIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder().addIssue(createIssue(SEVERITY_LEVEL_CRITICAL_WARNING))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withUnspecifiedStatusAndNoIssues_doesNotThrow() {
val builder = SafetySourceData.Builder().setStatus(createStatus(SEVERITY_LEVEL_UNSPECIFIED))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withUnspecifiedStatusAndInformationIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_UNSPECIFIED))
.addIssue(createIssue(SEVERITY_LEVEL_INFORMATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withInformationStatusAndNoIssues_doesNotThrow() {
val builder = SafetySourceData.Builder().setStatus(createStatus(SEVERITY_LEVEL_INFORMATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withInformationStatusAndInformationIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_INFORMATION))
.addIssue(createIssue(SEVERITY_LEVEL_INFORMATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withInformationStatusAndRecommendationIssues_throwsIllegalArgumentException() {
val builder =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_INFORMATION))
.addIssue(createIssue(SEVERITY_LEVEL_RECOMMENDATION))
val exception = assertFailsWith(IllegalArgumentException::class) { builder.build() }
assertThat(exception)
.hasMessageThat()
.isEqualTo(
"Safety source data must not contain any issue with a severity level both greater" +
" than SEVERITY_LEVEL_INFORMATION and greater than the status severity level")
}
@Test
fun build_withRecommendationStatusAndNoIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder().setStatus(createStatus(SEVERITY_LEVEL_RECOMMENDATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withRecommendationStatusAndInformationIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_RECOMMENDATION))
.addIssue(createIssue(SEVERITY_LEVEL_INFORMATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withRecommendationStatusAndRecommendationIssues_doesNotThrow() {
val builder =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_RECOMMENDATION))
.addIssue(createIssue(SEVERITY_LEVEL_RECOMMENDATION))
assertThat(builder.build()).isNotNull()
}
@Test
fun build_withRecommendationStatusAndCriticalIssues_throwsIllegalArgumentException() {
val builder =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_RECOMMENDATION))
.addIssue(createIssue(SEVERITY_LEVEL_CRITICAL_WARNING))
val exception = assertFailsWith(IllegalArgumentException::class) { builder.build() }
assertThat(exception)
.hasMessageThat()
.isEqualTo(
"Safety source data must not contain any issue with a severity level both greater" +
" than SEVERITY_LEVEL_INFORMATION and greater than the status severity level")
}
@Test
fun describeContents_returns0() {
val safetySourceData =
SafetySourceData.Builder().setStatus(createStatus(SEVERITY_LEVEL_INFORMATION)).build()
assertThat(safetySourceData.describeContents()).isEqualTo(0)
}
@Test
fun parcelRoundTrip_recreatesEqual() {
val safetySourceData =
SafetySourceData.Builder()
.setStatus(createStatus(SEVERITY_LEVEL_RECOMMENDATION))
.addIssue(createIssue(SEVERITY_LEVEL_RECOMMENDATION, 1))
.addIssue(createIssue(SEVERITY_LEVEL_INFORMATION, 2))
.build()
assertThat(safetySourceData).recreatesEqual(SafetySourceData.CREATOR)
}
@Test
fun equalsHashCodeToString_usingEqualsHashCodeToStringTester() {
val firstStatus = createStatus(SEVERITY_LEVEL_INFORMATION, 1)
val secondStatus = createStatus(SEVERITY_LEVEL_INFORMATION, 2)
val firstIssue = createIssue(SEVERITY_LEVEL_INFORMATION, 1)
val secondIssue = createIssue(SEVERITY_LEVEL_INFORMATION, 2)
EqualsHashCodeToStringTester()
.addEqualityGroup(
SafetySourceData.Builder().setStatus(firstStatus).build(),
SafetySourceData.Builder().setStatus(firstStatus).build())
.addEqualityGroup(
SafetySourceData.Builder().addIssue(firstIssue).addIssue(secondIssue).build(),
SafetySourceData.Builder().addIssue(firstIssue).addIssue(secondIssue).build())
.addEqualityGroup(
SafetySourceData.Builder()
.setStatus(firstStatus)
.addIssue(firstIssue)
.addIssue(secondIssue)
.build(),
SafetySourceData.Builder()
.setStatus(firstStatus)
.addIssue(firstIssue)
.addIssue(secondIssue)
.build())
.addEqualityGroup(SafetySourceData.Builder().setStatus(secondStatus).build())
.addEqualityGroup(
SafetySourceData.Builder().addIssue(secondIssue).addIssue(firstIssue).build())
.addEqualityGroup(SafetySourceData.Builder().addIssue(firstIssue).build())
.addEqualityGroup(
SafetySourceData.Builder()
.setStatus(secondStatus)
.addIssue(firstIssue)
.addIssue(secondIssue)
.build())
.test()
}
private fun createStatus(severityLevel: Int, id: Int = 0) =
SafetySourceStatus.Builder("Status title $id", "Status summary $id", severityLevel)
.setPendingIntent(
PendingIntent.getActivity(
context,
/* requestCode = */ 0,
Intent("Status PendingIntent $id"),
FLAG_IMMUTABLE))
.build()
private fun createIssue(severityLevel: Int, id: Int = 0) =
SafetySourceIssue.Builder(
"Issue id $id",
"Issue summary $id",
"Issue summary $id",
severityLevel,
"Issue type id $id")
.addAction(
SafetySourceIssue.Action.Builder(
"Action id $id",
"Action label $id",
PendingIntent.getActivity(
context,
/* requestCode = */ 0,
Intent("Issue PendingIntent $id"),
FLAG_IMMUTABLE))
.build())
.build()
}