Skip to content

Commit ab5adb4

Browse files
@W-21933885: [MSDK Android] App Attestation Implementation (Increase Test Code Coverage For AppAttestationChallengeApiClient)
1 parent 29e54a3 commit ab5adb4

3 files changed

Lines changed: 112 additions & 1 deletion

File tree

libs/SalesforceSDK/src/com/salesforce/androidsdk/rest/AppAttestationChallengeApiClient.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ internal class AppAttestationChallengeApiClient(
6868
)
6969
val restResponse = restClient.sendSync(restRequest)
7070
val responseBodyString = restResponse.asString()
71+
// TODO: Needs Coverage. ECJ20260416
7172
return if (restResponse.isSuccess && responseBodyString != null) {
7273
responseBodyString
7374
} else {
75+
// TODO: Needs Coverage. ECJ20260416
7476
throw AppAttestationChallengeApiException(
7577
source = responseBodyString
7678
)

libs/SalesforceSDK/src/com/salesforce/androidsdk/rest/AppAttestationChallengeApiException.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ package com.salesforce.androidsdk.rest
3434
* @param source The original Salesforce Mobile App Attestation Challenge API
3535
* error response body
3636
*/
37+
// TODO: Needs Coverage. ECJ20260416
3738
class AppAttestationChallengeApiException(
38-
val source: String
39+
val source: String?
3940
) : Exception()
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2026-present, salesforce.com, inc.
3+
* All rights reserved.
4+
* Redistribution and use of this software in source and binary forms, with or
5+
* without modification, are permitted provided that the following conditions
6+
* are met:
7+
* - Redistributions of source code must retain the above copyright notice, this
8+
* list of conditions and the following disclaimer.
9+
* - Redistributions in binary form must reproduce the above copyright notice,
10+
* this list of conditions and the following disclaimer in the documentation
11+
* and/or other materials provided with the distribution.
12+
* - Neither the name of salesforce.com, inc. nor the names of its contributors
13+
* may be used to endorse or promote products derived from this software without
14+
* specific prior written permission of salesforce.com, inc.
15+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25+
* POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
package com.salesforce.androidsdk.auth
28+
29+
import androidx.test.ext.junit.runners.AndroidJUnit4
30+
import com.salesforce.androidsdk.rest.AppAttestationChallengeApiClient
31+
import com.salesforce.androidsdk.rest.AppAttestationChallengeApiException
32+
import com.salesforce.androidsdk.rest.RestClient
33+
import com.salesforce.androidsdk.rest.RestResponse
34+
import io.mockk.every
35+
import io.mockk.mockk
36+
import org.junit.Assert.assertThrows
37+
import org.junit.Test
38+
import org.junit.runner.RunWith
39+
40+
@RunWith(AndroidJUnit4::class)
41+
class AppAttestationChallengeApiClientTest {
42+
43+
@Test
44+
fun appAttestationChallengeApiClient_fetchChallenge_throwsWhenRestResponseIsNotSuccess() {
45+
46+
val restResponse = mockk<RestResponse>(relaxed = true)
47+
every { restResponse.asString() } returns "__TEST_CHALLENGE_VALUE__"
48+
every { restResponse.isSuccess } returns false
49+
val restClient = mockk<RestClient>(relaxed = true)
50+
every { restClient.sendSync(any()) } returns restResponse
51+
52+
val appAttestationChallengeApiClient = AppAttestationChallengeApiClient(
53+
apiHostName = "https://www.example.com",
54+
restClient = restClient
55+
)
56+
57+
assertThrows(AppAttestationChallengeApiException::class.java) {
58+
appAttestationChallengeApiClient.fetchChallenge(
59+
attestationId = "__ATTESTATION_ID__",
60+
remoteConsumerKey = "__REMOTE_CONSUMER_KEY__"
61+
)
62+
}
63+
}
64+
65+
@Test
66+
fun appAttestationChallengeApiClient_fetchChallenge_throwsWhenRestResponseBodyStringIsNull() {
67+
68+
val restResponse = mockk<RestResponse>(relaxed = true)
69+
every { restResponse.asString() } returns null
70+
every { restResponse.isSuccess } returns true
71+
val restClient = mockk<RestClient>(relaxed = true)
72+
every { restClient.sendSync(any()) } returns restResponse
73+
74+
val appAttestationChallengeApiClient = AppAttestationChallengeApiClient(
75+
apiHostName = "https://www.example.com",
76+
restClient = restClient
77+
)
78+
79+
assertThrows(AppAttestationChallengeApiException::class.java) {
80+
appAttestationChallengeApiClient.fetchChallenge(
81+
attestationId = "__ATTESTATION_ID__",
82+
remoteConsumerKey = "__REMOTE_CONSUMER_KEY__"
83+
)
84+
}
85+
}
86+
87+
@Test
88+
fun appAttestationChallengeApiClient_fetchChallenge_throwsWhenRestResponseIsNotSuccessAndBodyStringIsNull() {
89+
90+
val restResponse = mockk<RestResponse>(relaxed = true)
91+
every { restResponse.asString() } returns null
92+
every { restResponse.isSuccess } returns false
93+
val restClient = mockk<RestClient>(relaxed = true)
94+
every { restClient.sendSync(any()) } returns restResponse
95+
96+
val appAttestationChallengeApiClient = AppAttestationChallengeApiClient(
97+
apiHostName = "https://www.example.com",
98+
restClient = restClient
99+
)
100+
101+
assertThrows(AppAttestationChallengeApiException::class.java) {
102+
appAttestationChallengeApiClient.fetchChallenge(
103+
attestationId = "__ATTESTATION_ID__",
104+
remoteConsumerKey = "__REMOTE_CONSUMER_KEY__"
105+
)
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)