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.intentresolver.validation
18 
19 import com.android.intentresolver.validation.types.value
20 import com.google.common.truth.Truth.assertThat
21 import org.junit.Assert.fail
22 import org.junit.Test
23 
24 class ValidationTest {
25 
26     /** Test required values. */
27     @Test
required_valuePresentnull28     fun required_valuePresent() {
29         val result: ValidationResult<String> =
30             validateFrom({ 1 }) {
31                 val required: Int = required(value<Int>("key"))
32                 "return value: $required"
33             }
34 
35         assertThat(result).isInstanceOf(Valid::class.java)
36         result as Valid<String>
37 
38         assertThat(result.value).isEqualTo("return value: 1")
39         assertThat(result.warnings).isEmpty()
40     }
41 
42     /** Test reporting of absent required values. */
43     @Test
required_valueAbsentnull44     fun required_valueAbsent() {
45         val result: ValidationResult<String> =
46             validateFrom({ null }) {
47                 required(value<Int>("key"))
48                 fail("'required' should have thrown an exception")
49                 "return value"
50             }
51 
52         assertThat(result).isInstanceOf(Invalid::class.java)
53         result as Invalid<String>
54 
55         assertThat(result.errors).containsExactly(NoValue("key", Importance.CRITICAL, Int::class))
56     }
57 
58     /** Test optional values are ignored when absent. */
59     @Test
optional_valuePresentnull60     fun optional_valuePresent() {
61         val result: ValidationResult<String> =
62             validateFrom({ 1 }) {
63                 val optional: Int? = optional(value<Int>("key"))
64                 "return value: $optional"
65             }
66 
67         assertThat(result).isInstanceOf(Valid::class.java)
68         result as Valid<String>
69 
70         assertThat(result.value).isEqualTo("return value: 1")
71         assertThat(result.warnings).isEmpty()
72     }
73 
74     /** Test optional values are ignored when absent. */
75     @Test
optional_valueAbsentnull76     fun optional_valueAbsent() {
77         val result: ValidationResult<String> =
78             validateFrom({ null }) {
79                 val optional: String? = optional(value<String>("key"))
80                 "return value: $optional"
81             }
82 
83         assertThat(result).isInstanceOf(Valid::class.java)
84         result as Valid<String>
85 
86         assertThat(result.value).isEqualTo("return value: null")
87         assertThat(result.warnings).isEmpty()
88     }
89 
90     /** Test reporting of ignored values. */
91     @Test
ignored_valuePresentnull92     fun ignored_valuePresent() {
93         val result: ValidationResult<String> =
94             validateFrom(mapOf("key" to 1)::get) {
95                 ignored(value<Int>("key"), "no longer supported")
96                 "result value"
97             }
98 
99         assertThat(result).isInstanceOf(Valid::class.java)
100         result as Valid<String>
101 
102         assertThat(result.value).isEqualTo("result value")
103         assertThat(result.warnings).containsExactly(IgnoredValue("key", "no longer supported"))
104     }
105 
106     /** Test reporting of ignored values. */
107     @Test
ignored_valueAbsentnull108     fun ignored_valueAbsent() {
109         val result: ValidationResult<String> =
110             validateFrom({ null }) {
111                 ignored(value<Int>("key"), "ignored when option foo is set")
112                 "result value"
113             }
114         assertThat(result).isInstanceOf(Valid::class.java)
115         result as Valid<String>
116 
117         assertThat(result.value).isEqualTo("result value")
118         assertThat(result.warnings).isEmpty()
119     }
120 
121     /** Test handling of exceptions in the validation function. */
122     @Test
thrown_exceptionnull123     fun thrown_exception() {
124         val result: ValidationResult<String> = validateFrom({ null }) { error("something") }
125 
126         assertThat(result).isInstanceOf(Invalid::class.java)
127         result as Invalid<String>
128 
129         val errorType = result.errors.map { it::class }.first()
130         assertThat(errorType).isEqualTo(UncaughtException::class)
131     }
132 }
133