Skip to content

Commit

Permalink
Merge pull request #73 from velocitycareerlabs/VL-6698
Browse files Browse the repository at this point in the history
Vl 6698
  • Loading branch information
michaelavoyan authored Jan 1, 2024
2 parents 5ee9a95 + 7c0eac5 commit bb8ae23
Show file tree
Hide file tree
Showing 23 changed files with 289 additions and 83 deletions.
4 changes: 2 additions & 2 deletions VCL/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
defaultConfig {
minSdk 24
targetSdk 33
versionName "1.22.2"
versionCode 118
versionName "1.23.0"
versionCode 119
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ class VCLError(
): Error() {
var payload: String? = null
var error: String? = null
var errorCode: String? = null
var errorCode: String = VCLErrorCode.SdkError.value
override var message: String? = null
var statusCode: Int? = null

constructor(
error: String? = null,
errorCode: String? = null,
errorCode: String = VCLErrorCode.SdkError.value,
message: String? = null,
statusCode: Int? = null,
) : this() {
Expand All @@ -34,15 +34,15 @@ class VCLError(
val payloadJson = payload?.toJsonObject()
this.payload = payload
this.error = payloadJson?.optString(KeyError)
this.errorCode = errorCode ?: payloadJson?.optString(KeyErrorCode)
this.errorCode = errorCode ?: payloadJson?.optString(KeyErrorCode) ?: VCLErrorCode.SdkError.value
this.message = payloadJson?.optString(KeyMessage)
this.statusCode = payloadJson?.optInt(KeyStatusCode)
}

constructor(exception: Exception, statusCode: Int? = null): this() {
this.payload = null
this.error = null
this.errorCode = null
this.errorCode = VCLErrorCode.SdkError.value
this.message = exception.toString()
this.statusCode = statusCode
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

package io.velocitycareerlabs.api.entities.error

internal enum class VCLErrorCode(val value: String) {
enum class VCLErrorCode(val value: String) {
// Initialization
RemoteServicesUrlsNotFount("remote_services_urls_not_found"),
InjectedServicesNotFount("injected_services_not_found"),
Expand All @@ -22,5 +22,7 @@ internal enum class VCLErrorCode(val value: String) {
MismatchedRequestIssuerDid("mismatched_request_issuer_did"),
MismatchedOfferIssuerDid("mismatched_offer_issuer_did"),
MismatchedCredentialIssuerDid("mismatched_credential_issuer_did"),
MismatchedPresentationRequestInspectorDid("mismatched_presentation_request_inspector_did")
MismatchedPresentationRequestInspectorDid("mismatched_presentation_request_inspector_did"),
// General error
SdkError("sdk_error")
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import io.velocitycareerlabs.api.entities.error.VCLError
import io.velocitycareerlabs.impl.data.infrastructure.network.Request
import io.velocitycareerlabs.impl.domain.repositories.SubmissionRepository
import io.velocitycareerlabs.impl.domain.infrastructure.network.NetworkService
import io.velocitycareerlabs.impl.extensions.toJsonObject
import org.json.JSONObject
import java.lang.Exception

Expand All @@ -34,9 +35,8 @@ internal class SubmissionRepositoryImpl(
completionBlock = { result ->
result.handleResult({ submissionResponse ->
try {
val jsonObj = JSONObject(submissionResponse.payload)
val submissionResult =
parse(jsonObj, submission.jti, submission.submissionId)
val jsonObj = submissionResponse.payload.toJsonObject()
val submissionResult = parse(jsonObj, submission.jti, submission.submissionId)
completionBlock(VCLResult.Success(submissionResult))
} catch (ex: Exception) {
completionBlock(VCLResult.Failure(VCLError(ex)))
Expand All @@ -51,13 +51,13 @@ internal class SubmissionRepositoryImpl(
}

private fun parse(
jsonObj: JSONObject,
jsonObj: JSONObject?,
jti: String,
submissionId: String
): VCLSubmissionResult {
val exchangeJsonObj = jsonObj.optJSONObject(VCLSubmissionResult.KeyExchange)
val exchangeJsonObj = jsonObj?.optJSONObject(VCLSubmissionResult.KeyExchange)
return VCLSubmissionResult(
sessionToken = VCLToken(jsonObj.optString(VCLSubmissionResult.KeyToken)),
sessionToken = VCLToken(jsonObj?.optString(VCLSubmissionResult.KeyToken) ?: ""),
exchange = parseExchange(exchangeJsonObj),
jti = jti,
submissionId = submissionId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ class DeepLinkMocks {

const val OpenidInitiateIssuanceStrDev = "openid-initiate-issuance://?issuer=$Issuer"

const val InspectorDid = "did:ion:EiByBvq95tfmhl41DOxJeaa26HjSxAUoz908PITFwMRDNA"
const val InspectorDid = "did:velocity:0xd4df29726d500f9b85bc6c7f1b3c021f16305692"

const val PresentationRequestVendorOriginContext =
"{\"SubjectKey\":{\"BusinessUnit\":\"ZC\",\"KeyCode\":\"54514480\"},\"Token\":\"832077a4\"}"

var PresentationRequestRequestDecodedUriStr =
"https://agent.velocitycareerlabs.io/api/holder/v0.6/org/$InspectorDid/inspect/get-presentation-request?id=62e0e80c5ebfe73230b0becc&inspectorDid=${InspectorDid.encode()}&vendorOriginContext=%7B%22SubjectKey%22%3A%7B%22BusinessUnit%22%3A%22ZC%22,%22KeyCode%22%3A%2254514480%22%7D,%22Token%22%3A%22832077a4%22%7D".decode()
"https://agent.velocitycareerlabs.io/api/holder/v0.6/org/$InspectorDid/inspect/get-presentation-request?id=62e0e80c5ebfe73230b0becc&inspectorDid=${InspectorDid}&vendorOriginContext=%7B%22SubjectKey%22%3A%7B%22BusinessUnit%22%3A%22ZC%22,%22KeyCode%22%3A%2254514480%22%7D,%22Token%22%3A%22832077a4%22%7D".decode()

const val PresentationRequestRequestUriStr =
"https%3A%2F%2Fagent.velocitycareerlabs.io%2Fapi%2Fholder%2Fv0.6%2Forg%2Fdid%3Aion%3AEiByBvq95tfmhl41DOxJeaa26HjSxAUoz908PITFwMRDNA%2Finspect%2Fget-presentation-request%3Fid%3D62e0e80c5ebfe73230b0becc&inspectorDid=did%3Aion%3AEiByBvq95tfmhl41DOxJeaa26HjSxAUoz908PITFwMRDNA&vendorOriginContext=%7B%22SubjectKey%22%3A%7B%22BusinessUnit%22%3A%22ZC%22,%22KeyCode%22%3A%2254514480%22%7D,%22Token%22%3A%22832077a4%22%7D"
"https%3A%2F%2Fagent.velocitycareerlabs.io%2Fapi%2Fholder%2Fv0.6%2Forg%2Fdid%3Avelocity%3A0xd4df29726d500f9b85bc6c7f1b3c021f16305692%2Finspect%2Fget-presentation-request%3Fid%3D62e0e80c5ebfe73230b0becc%26inspectorDid%3Ddid%3Avelocity%3A0xd4df29726d500f9b85bc6c7f1b3c021f16305692%26vendorOriginContext%3D%7B%22SubjectKey%22%3A%7B%22BusinessUnit%22%3A%22ZC%22%2C%22KeyCode%22%3A%2254514480%22%7D%2C%22Token%22%3A%22832077a4%22%7D"

const val PresentationRequestDeepLinkDevNetStr =
"$DevNetProtocol://inspect?request_uri=$PresentationRequestRequestUriStr"
Expand All @@ -42,13 +42,13 @@ class DeepLinkMocks {
const val PresentationRequestDeepLinkMainNetStr =
"$MainNetProtocol://inspect?request_uri=$PresentationRequestRequestUriStr"

const val IssuerDid = "did:velocity:0xd4df29726d500f9b85bc6c7f1b3c021f16305692"
const val IssuerDid = "did:ion:EiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA"

const val CredentialManifestRequestDecodedUriStr =
"https://devagent.velocitycareerlabs.io/api/holder/v0.6/org/$IssuerDid/issue/get-credential-manifest?id=611b5836e93d08000af6f1bc&credential_types=PastEmploymentPosition&issuerDid=did:velocity:0xd4df29726d500f9b85bc6c7f1b3c021f16305692"
"https://devagent.velocitycareerlabs.io/api/holder/v0.6/org/$IssuerDid/issue/get-credential-manifest?id=611b5836e93d08000af6f1bc&credential_types=PastEmploymentPosition&issuerDid=$IssuerDid"

const val CredentialManifestRequestUriStr =
"https%3A%2F%2Fdevagent.velocitycareerlabs.io%2Fapi%2Fholder%2Fv0.6%2Forg%2Fdid%3Avelocity%3A0xd4df29726d500f9b85bc6c7f1b3c021f16305692%2Fissue%2Fget-credential-manifest%3Fid%3D611b5836e93d08000af6f1bc%26credential_types%3DPastEmploymentPosition%26issuerDid%3Ddid%3Avelocity%3A0xd4df29726d500f9b85bc6c7f1b3c021f16305692"
"https%3A%2F%2Fdevagent.velocitycareerlabs.io%2Fapi%2Fholder%2Fv0.6%2Forg%2Fdid%3Aion%3AEiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA%2Fissue%2Fget-credential-manifest%3Fid%3D611b5836e93d08000af6f1bc%26credential_types%3DPastEmploymentPosition%26issuerDid%3Ddid%3Aion%3AEiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA"

const val CredentialManifestDeepLinkDevNetStr = "$DevNetProtocol://issue?request_uri=$CredentialManifestRequestUriStr"
const val CredentialManifestDeepLinkTestNetStr = "$TestNetProtocol://issue?request_uri=$CredentialManifestRequestUriStr"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ class PresentationRequestMocks {
const val EncodedPresentationRequestResponse =
"{\"presentation_request\":\"$EncodedPresentationRequest\"}"

const val PresentationRequestJwtDecodedHeaderJson =
"{ \"typ\": \"JWT\", \"kid\": \"did:velocity:0xd4df29726d500f9b85bc6c7f1b3c021f16305692#key-1\", \"alg\": \"ES256K\" }"

const val PresentationRequestJwtDecodedPayloadJson =
"{ \"exchange_id\": \"60ec1f766d274e00086748ca\", \"metadata\": { \"client_name\": \"Microsoft Corporation\", \"logo_uri\": \"https://agsol.com/wp-content/uploads/2018/09/new-microsoft-logo-SIZED-SQUARE.jpg\", \"tos_uri\": \"https://www.velocityexperiencecenter.com/terms-and-conditions-vnf\", \"max_retention_period\": \"6m\" }, \"presentation_definition\": { \"id\": \"60ec1f766d274e00086748ca.60ec143e6d274e00086748bc\", \"purpose\": \"Id Check\", \"format\": { \"jwt_vp\": { \"alg\": [ \"secp256k1\" ] } }, \"input_descriptors\": [ { \"id\": \"IdDocument\", \"schema\": [ { \"uri\": \"https://devservices.velocitycareerlabs.io/api/v0.6/schemas/id-document.v1.schema.json\" } ] }, { \"id\": \"Email\", \"schema\": [ { \"uri\": \"https://devservices.velocitycareerlabs.io/api/v0.6/schemas/email.schema.json\" } ] }, { \"id\": \"Phone\", \"schema\": [ { \"uri\": \"https://devservices.velocitycareerlabs.io/api/v0.6/schemas/phone.schema.json\" } ] }, { \"id\": \"PastEmploymentPosition\", \"schema\": [ { \"uri\": \"https://devservices.velocitycareerlabs.io/api/v0.6/schemas/past-employment-position.schema.json\" } ] }, { \"id\": \"CurrentEmploymentPosition\", \"schema\": [ { \"uri\": \"https://devservices.velocitycareerlabs.io/api/v0.6/schemas/current-employment-position.schema.json\" } ] }, { \"id\": \"EducationDegree\", \"schema\": [ { \"uri\": \"https://devservices.velocitycareerlabs.io/api/v0.6/schemas/education-degree.schema.json\" } ] } ] }, \"iss\": \"did:velocity:0xd4df29726d500f9b85bc6c7f1b3c021f16305692\", \"iat\": 1626087286, \"exp\": 1626692086, \"nbf\": 1626087286 }"

const val PresentationRequestJwtSignature =
"BSQnMNNJyicCsh6zeh7k5GBHC6T9QgPNV4SHhSXsnz3sBJMwNBFz7v4axLCoCiKHtIxNj5"

val PresentationRequestJwt = VCLJwt(
encodedJwt = EncodedPresentationRequest
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@

package io.velocitycareerlabs.usecases

import android.os.Build
import io.velocitycareerlabs.api.entities.VCLCountries
import io.velocitycareerlabs.api.entities.error.VCLErrorCode
import io.velocitycareerlabs.api.entities.handleResult
import io.velocitycareerlabs.impl.data.infrastructure.executors.ExecutorImpl
import io.velocitycareerlabs.impl.data.repositories.CountriesRepositoryImpl
import io.velocitycareerlabs.impl.data.usecases.CountriesUseCaseImpl
import io.velocitycareerlabs.impl.domain.usecases.CountriesUseCase
import io.velocitycareerlabs.infrastructure.resources.EmptyCacheService
import io.velocitycareerlabs.infrastructure.network.NetworkServiceSuccess
import io.velocitycareerlabs.infrastructure.resources.EmptyExecutor
import io.velocitycareerlabs.infrastructure.resources.valid.CountriesMocks
import org.junit.After
import org.junit.Before
import org.junit.Test

//@RunWith(RobolectricTestRunner::class)
//@Config(sdk = [Build.VERSION_CODES.O_MR1])
class CountriesUseCaseTest {

internal lateinit var subject: CountriesUseCase
Expand Down Expand Up @@ -59,7 +60,31 @@ class CountriesUseCaseTest {
assert(afghanistanRegions.all[2].code == CountriesMocks.AfghanistanRegion3Code)
},
errorHandler = {
assert(false) { "$it" }
assert(false) { "${it.toJsonObject()}" }
}
)
}
}

@Test
fun testGetCountriesFailure() {
subject = CountriesUseCaseImpl(
CountriesRepositoryImpl(
NetworkServiceSuccess(
"wrong payload"
),
EmptyCacheService()
),
EmptyExecutor()
)

subject.getCountries(0) {
it.handleResult(
successHandler = {
assert(false) { "${VCLErrorCode.SdkError.value} error code is expected" }
},
errorHandler = { error ->
assert(error.errorCode == VCLErrorCode.SdkError.value)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package io.velocitycareerlabs.usecases

import android.os.Build
import io.velocitycareerlabs.api.entities.*
import io.velocitycareerlabs.api.entities.error.VCLErrorCode
import io.velocitycareerlabs.impl.data.infrastructure.executors.ExecutorImpl
import io.velocitycareerlabs.impl.keys.VCLKeyServiceLocalImpl
import io.velocitycareerlabs.impl.data.repositories.CredentialManifestRepositoryImpl
Expand All @@ -22,6 +23,7 @@ import io.velocitycareerlabs.impl.jwt.local.VCLJwtSignServiceLocalImpl
import io.velocitycareerlabs.impl.jwt.local.VCLJwtVerifyServiceLocalImpl
import io.velocitycareerlabs.infrastructure.db.SecretStoreServiceMock
import io.velocitycareerlabs.infrastructure.network.NetworkServiceSuccess
import io.velocitycareerlabs.infrastructure.resources.EmptyExecutor
import io.velocitycareerlabs.infrastructure.resources.valid.CredentialManifestMocks
import io.velocitycareerlabs.infrastructure.resources.valid.DeepLinkMocks
import io.velocitycareerlabs.infrastructure.resources.valid.VerifiedProfileMocks
Expand All @@ -45,7 +47,7 @@ internal class CredentialManifestUseCaseTest {
}

@Test
fun testGetCredentialManifest() {
fun testGetCredentialManifestSuccess() {
// Arrange
subject = CredentialManifestUseCaseImpl(
CredentialManifestRepositoryImpl(
Expand All @@ -59,7 +61,7 @@ internal class CredentialManifestUseCaseTest {
VCLJwtVerifyServiceLocalImpl()
),
CredentialManifestByDeepLinkVerifierImpl(),
ExecutorImpl()
EmptyExecutor()
)

subject.getCredentialManifest(
Expand Down Expand Up @@ -91,7 +93,44 @@ internal class CredentialManifestUseCaseTest {
assert(credentialManifest.jwt.signature.toString() == CredentialManifestMocks.Signature)
},
{
assert(false) { "$it" }
assert(false) { "${it.toJsonObject()}" }
}
)
}
}

@Test
fun testGetCredentialManifestFailure() {
// Arrange
subject = CredentialManifestUseCaseImpl(
CredentialManifestRepositoryImpl(
NetworkServiceSuccess("wrong payload")
),
ResolveKidRepositoryImpl(
NetworkServiceSuccess(CredentialManifestMocks.JWK)
),
JwtServiceRepositoryImpl(
VCLJwtSignServiceLocalImpl(VCLKeyServiceLocalImpl(SecretStoreServiceMock.Instance)),
VCLJwtVerifyServiceLocalImpl()
),
CredentialManifestByDeepLinkVerifierImpl(),
EmptyExecutor()
)

subject.getCredentialManifest(
credentialManifestDescriptor = VCLCredentialManifestDescriptorByDeepLink(
deepLink = DeepLinkMocks.CredentialManifestDeepLinkDevNet,
issuingType = VCLIssuingType.Career
),
verifiedProfile = VCLVerifiedProfile(VerifiedProfileMocks.VerifiedProfileIssuerJsonStr1.toJsonObject()!!),
remoteCryptoServicesToken = null
) {
it.handleResult(
successHandler = {
assert(false) { "${VCLErrorCode.SdkError.value} error code is expected" }
},
errorHandler = { error ->
assert(error.errorCode == VCLErrorCode.SdkError.value)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.velocitycareerlabs.impl.data.usecases.CredentialTypeSchemasUseCaseImpl
import io.velocitycareerlabs.impl.domain.usecases.CredentialTypeSchemasUseCase
import io.velocitycareerlabs.infrastructure.resources.EmptyCacheService
import io.velocitycareerlabs.infrastructure.network.NetworkServiceSuccess
import io.velocitycareerlabs.infrastructure.resources.EmptyExecutor
import io.velocitycareerlabs.infrastructure.resources.valid.CredentialTypeSchemaMocks
import org.json.JSONObject
import org.junit.After
Expand All @@ -36,7 +37,7 @@ internal class CredentialTypeSchemaUseCaseTest {
EmptyCacheService()
),
CredentialTypeSchemaMocks.CredentialTypes,
ExecutorImpl()
EmptyExecutor()
)

subject.getCredentialTypeSchemas(0) {
Expand Down
Loading

0 comments on commit bb8ae23

Please sign in to comment.