1 /*
2  * Copyright (C) 2019 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 android.net
18 
19 import android.os.Build
20 import androidx.test.filters.SmallTest
21 import com.android.modules.utils.build.SdkLevel
22 import com.android.testutils.assertParcelingIsLossless
23 import com.android.testutils.DevSdkIgnoreRule
24 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
25 import com.android.testutils.DevSdkIgnoreRunner
26 import org.junit.Assert.assertFalse
27 import org.junit.Assert.assertTrue
28 import org.junit.Rule
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import kotlin.test.assertEquals
32 import kotlin.test.assertNotEquals
33 
34 @SmallTest
35 @RunWith(DevSdkIgnoreRunner::class)
36 @IgnoreUpTo(Build.VERSION_CODES.Q)
37 class CaptivePortalDataTest {
38     @Rule @JvmField
39     val ignoreRule = DevSdkIgnoreRule()
40 
41     private val data = CaptivePortalData.Builder()
42             .setRefreshTime(123L)
43             .setUserPortalUrl(Uri.parse("https://portal.example.com/test"))
44             .setVenueInfoUrl(Uri.parse("https://venue.example.com/test"))
45             .setSessionExtendable(true)
46             .setBytesRemaining(456L)
47             .setExpiryTime(789L)
48             .setCaptive(true)
49             .apply {
50                 if (SdkLevel.isAtLeastS()) {
51                     setVenueFriendlyName("venue friendly name")
52                 }
53             }
54             .build()
55 
56     private val dataFromPasspoint = CaptivePortalData.Builder()
57             .setCaptive(true)
58             .apply {
59                 if (SdkLevel.isAtLeastS()) {
60                     setVenueFriendlyName("venue friendly name")
61                     setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"),
62                             CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
63                     setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"),
64                             CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
65                 }
66             }
67             .build()
68 
69     private fun makeBuilder() = CaptivePortalData.Builder(data)
70 
71     @Test
72     fun testParcelUnparcel() {
73         assertParcelingIsLossless(data)
74         assertParcelingIsLossless(dataFromPasspoint)
75 
76         assertParcelingIsLossless(makeBuilder().setUserPortalUrl(null).build())
77         assertParcelingIsLossless(makeBuilder().setVenueInfoUrl(null).build())
78     }
79 
80     @Test
81     fun testEquals() {
82         assertEquals(data, makeBuilder().build())
83 
84         assertNotEqualsAfterChange { it.setRefreshTime(456L) }
85         assertNotEqualsAfterChange { it.setUserPortalUrl(Uri.parse("https://example.com/")) }
86         assertNotEqualsAfterChange { it.setUserPortalUrl(null) }
87         assertNotEqualsAfterChange { it.setVenueInfoUrl(Uri.parse("https://example.com/")) }
88         assertNotEqualsAfterChange { it.setVenueInfoUrl(null) }
89         assertNotEqualsAfterChange { it.setSessionExtendable(false) }
90         assertNotEqualsAfterChange { it.setBytesRemaining(789L) }
91         assertNotEqualsAfterChange { it.setExpiryTime(12L) }
92         assertNotEqualsAfterChange { it.setCaptive(false) }
93 
94         if (SdkLevel.isAtLeastS()) {
95             assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
96             assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
97 
98             assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build())
99             assertNotEqualsAfterChange { it.setUserPortalUrl(
100                     Uri.parse("https://tc.example.com/passpoint")) }
101             assertNotEqualsAfterChange { it.setUserPortalUrl(
102                     Uri.parse("https://tc.example.com/passpoint"),
103                     CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
104             assertNotEqualsAfterChange { it.setUserPortalUrl(
105                     Uri.parse("https://tc.example.com/other"),
106                     CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
107             assertNotEqualsAfterChange { it.setUserPortalUrl(
108                     Uri.parse("https://tc.example.com/passpoint"),
109                     CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
110             assertNotEqualsAfterChange { it.setVenueInfoUrl(
111                     Uri.parse("https://venue.example.com/passpoint")) }
112             assertNotEqualsAfterChange { it.setVenueInfoUrl(
113                     Uri.parse("https://venue.example.com/other"),
114                     CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
115             assertNotEqualsAfterChange { it.setVenueInfoUrl(
116                     Uri.parse("https://venue.example.com/passpoint"),
117                     CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
118         }
119     }
120 
121     @Test
122     fun testUserPortalUrl() {
123         assertEquals(Uri.parse("https://portal.example.com/test"), data.userPortalUrl)
124     }
125 
126     @Test
127     fun testVenueInfoUrl() {
128         assertEquals(Uri.parse("https://venue.example.com/test"), data.venueInfoUrl)
129     }
130 
131     @Test
132     fun testIsSessionExtendable() {
133         assertTrue(data.isSessionExtendable)
134     }
135 
136     @Test
137     fun testByteLimit() {
138         assertEquals(456L, data.byteLimit)
139         // Test byteLimit unset.
140         assertEquals(-1L, CaptivePortalData.Builder(null).build().byteLimit)
141     }
142 
143     @Test
144     fun testRefreshTimeMillis() {
145         assertEquals(123L, data.refreshTimeMillis)
146     }
147 
148     @Test
149     fun testExpiryTimeMillis() {
150         assertEquals(789L, data.expiryTimeMillis)
151         // Test expiryTimeMillis unset.
152         assertEquals(-1L, CaptivePortalData.Builder(null).build().expiryTimeMillis)
153     }
154 
155     @Test
156     fun testIsCaptive() {
157         assertTrue(data.isCaptive)
158         assertFalse(makeBuilder().setCaptive(false).build().isCaptive)
159     }
160 
161     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
162     fun testVenueFriendlyName() {
163         assertEquals("venue friendly name", data.venueFriendlyName)
164     }
165 
166     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
167     fun testGetVenueInfoUrlSource() {
168         assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER,
169                 data.venueInfoUrlSource)
170         assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT,
171                 dataFromPasspoint.venueInfoUrlSource)
172     }
173 
174     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
175     fun testGetUserPortalUrlSource() {
176         assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER,
177                 data.userPortalUrlSource)
178         assertEquals(CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT,
179                 dataFromPasspoint.userPortalUrlSource)
180     }
181 
182     private fun CaptivePortalData.mutate(mutator: (CaptivePortalData.Builder) -> Unit) =
183             CaptivePortalData.Builder(this).apply { mutator(this) }.build()
184 
185     private fun assertNotEqualsAfterChange(mutator: (CaptivePortalData.Builder) -> Unit) {
186         assertNotEquals(data, data.mutate(mutator))
187     }
188 }