Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sdk/src/main/kotlin/com/idme/auth/IDmeAuth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ class IDmeAuth(
*/
suspend fun attributes(): AttributeResponse {
val creds = tokenManager.validCredentials(60)
val url = APIEndpoint.userInfo(configuration.environment)
val url = APIEndpoint.attributes(configuration.environment)

val headers = mapOf("Authorization" to "Bearer ${creds.accessToken}")

Expand Down
4 changes: 4 additions & 0 deletions sdk/src/main/kotlin/com/idme/auth/networking/APIEndpoint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ object APIEndpoint {
fun userInfo(environment: IDmeEnvironment): String =
"${environment.apiBaseURL}api/public/v3/userinfo"

/** Attributes endpoint (OAuth mode). */
fun attributes(environment: IDmeEnvironment): String =
"${environment.apiBaseURL}api/public/v3/attributes.json"

/** Policies endpoint. */
fun policies(environment: IDmeEnvironment): String =
"${environment.apiBaseURL}api/public/v3/policies"
Expand Down
78 changes: 78 additions & 0 deletions sdk/src/test/kotlin/com/idme/auth/IDmeAuthAttributesTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.idme.auth

import com.idme.auth.mocks.MockCredentialStore
import com.idme.auth.mocks.MockHTTPClient
import com.idme.auth.mocks.MockJWKSFetcher
import com.idme.auth.mocks.MockTokenRefresher
import com.idme.auth.mocks.TestFixtures
import com.idme.auth.token.TokenManager
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class IDmeAuthAttributesTest {

private val attributesJson = """
{
"attributes": [
{"handle": "email", "name": "Email", "value": "test@example.com"},
{"handle": "fname", "name": "First Name", "value": "John"}
],
"status": [
{"group": "military", "subgroups": ["Veteran"], "verified": true}
]
}
""".trimIndent()

private fun buildAuth(httpClient: MockHTTPClient): IDmeAuth {
val store = MockCredentialStore()
store.save(TestFixtures.makeCredentials(expiresInMs = 3_600_000))
return IDmeAuth(
configuration = TestFixtures.singleConfig,
tokenManager = TokenManager(store, MockTokenRefresher()),
httpClient = httpClient,
jwksFetcher = MockJWKSFetcher()
)
}

@Test
fun `attributes calls attributes endpoint not userinfo`() = runTest {
val httpClient = MockHTTPClient()
httpClient.enqueue(body = attributesJson, statusCode = 200)

buildAuth(httpClient).attributes()

val calledURL = httpClient.capturedRequests.single().url
assertTrue(
"Expected /api/public/v3/attributes.json but got: $calledURL",
calledURL.endsWith("api/public/v3/attributes.json")
)
}

@Test
fun `attributes returns populated status block`() = runTest {
val httpClient = MockHTTPClient()
httpClient.enqueue(body = attributesJson, statusCode = 200)

val result = buildAuth(httpClient).attributes()

assertEquals(1, result.status.size)
val status = result.status[0]
assertEquals("military", status.group)
assertTrue(status.verified)
assertEquals(listOf("Veteran"), status.subgroups)
}

@Test
fun `attributes returns populated attributes list`() = runTest {
val httpClient = MockHTTPClient()
httpClient.enqueue(body = attributesJson, statusCode = 200)

val result = buildAuth(httpClient).attributes()

assertEquals(2, result.attributes.size)
val email = result.attributes.first { it.handle == "email" }
assertEquals("test@example.com", email.value)
}
}
Loading