Skip to content

Commit d96fd77

Browse files
committed
PYIC-7634: Add new BAV contract test scenario
The BAV CRI can now return a failed VC that does not contain a CI
1 parent 709ee95 commit d96fd77

File tree

1 file changed

+180
-2
lines changed
  • lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/bavCri

1 file changed

+180
-2
lines changed

lambdas/process-cri-callback/src/test/java/uk/gov/di/ipv/core/processcricallback/pact/bavCri/ContractTest.java

+180-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
import static org.hamcrest.CoreMatchers.notNullValue;
5757
import static org.hamcrest.MatcherAssert.assertThat;
5858
import static org.hamcrest.Matchers.greaterThan;
59-
import static org.junit.jupiter.api.Assertions.assertEquals;
60-
import static org.junit.jupiter.api.Assertions.assertThrows;
59+
import static org.junit.jupiter.api.Assertions.*;
6160
import static org.mockito.ArgumentMatchers.any;
6261
import static org.mockito.Mockito.when;
6362
import static uk.gov.di.ipv.core.library.domain.Cri.BAV;
@@ -305,6 +304,119 @@ void fetchVerifiableCredential_whenCalledAgainstBavCri_retrievesAVcWithACi(
305304
});
306305
}
307306

307+
@Pact(provider = "BavCriProvider", consumer = "IpvCoreBack")
308+
public RequestResponsePact validRequestReturnsBavResponseWithoutCi(
309+
PactDslWithProvider builder) {
310+
return builder.given("dummyApiKey is a valid api key")
311+
.given("test-subject is a valid subject")
312+
.given("dummyBavComponentId is a valid issuer")
313+
.given("VC evidence failedCheckDetails identityCheckPolicy is none")
314+
.given("VC evidence failedCheckDetails checkMethod is data")
315+
.given("VC evidence validityScore is 0")
316+
.given("VC evidence strengthScore is 3")
317+
.given("VC evidence txn is dummyTxn")
318+
.given("VC evidence credentialSubject contains bankAccount")
319+
.given("VC bankAccount accountNumber is 11111117")
320+
.given("VC bankAccount sortCode is 204578")
321+
.given("VC is for Bob Fossil")
322+
.uponReceiving("Valid credential request for BAV failed VC with no CIs")
323+
.path("/userinfo")
324+
.method("POST")
325+
.headers("x-api-key", PRIVATE_API_KEY, "Authorization", "Bearer dummyAccessToken")
326+
.willRespondWith()
327+
.status(200)
328+
.body(
329+
newJsonBody(
330+
body -> {
331+
var jwtBuilder =
332+
new PactJwtBuilder(
333+
VALID_VC_HEADER,
334+
FAILED_BAV_NO_CI_VC_BODY,
335+
FAILED_BAV_NO_CI_VC_SIGNATURE);
336+
337+
body.stringValue("sub", "test-subject");
338+
body.minMaxArrayLike(
339+
"https://vocab.account.gov.uk/v1/credentialJWT",
340+
1,
341+
1,
342+
PactDslJsonRootValue.stringMatcher(
343+
jwtBuilder
344+
.buildRegexMatcherIgnoringSignature(),
345+
jwtBuilder.buildJwt()),
346+
1);
347+
})
348+
.build())
349+
.toPact();
350+
}
351+
352+
@Test
353+
@PactTestFor(pactMethod = "validRequestReturnsBavResponseWithoutCi")
354+
void fetchVerifiableCredential_whenCalledAgainstBavCri_retrievesAVcWithoutACi(
355+
MockServer mockServer)
356+
throws URISyntaxException, CriApiException, JsonProcessingException {
357+
// Arrange
358+
var credentialIssuerConfig = getMockCredentialIssuerConfig(mockServer);
359+
configureMockConfigService(credentialIssuerConfig);
360+
361+
// We need to generate a fixed request, so we set the secure token and expiry to constant
362+
// values.
363+
var underTest =
364+
new CriApiService(
365+
mockConfigService, mockSignerFactory, mockSecureTokenHelper, CURRENT_TIME);
366+
367+
// Act
368+
var verifiableCredentialResponse =
369+
underTest.fetchVerifiableCredential(
370+
new BearerAccessToken("dummyAccessToken"), BAV, CRI_OAUTH_SESSION_ITEM);
371+
372+
// Assert
373+
var verifiableCredentialJwtValidator = getVerifiableCredentialJwtValidator();
374+
verifiableCredentialResponse
375+
.getVerifiableCredentials()
376+
.forEach(
377+
credential -> {
378+
System.out.println(credential);
379+
try {
380+
var vc =
381+
verifiableCredentialJwtValidator.parseAndValidate(
382+
TEST_USER,
383+
BAV,
384+
credential,
385+
EC_PRIVATE_KEY_JWK,
386+
TEST_ISSUER,
387+
false);
388+
389+
JsonNode vcClaim =
390+
OBJECT_MAPPER
391+
.readTree(vc.getClaimsSet().toString())
392+
.get("vc");
393+
394+
JsonNode credentialSubject = vcClaim.get("credentialSubject");
395+
JsonNode evidence = vcClaim.get("evidence").get(0);
396+
397+
JsonNode ciNode = evidence.get("ci");
398+
JsonNode nameParts =
399+
credentialSubject.get("name").get(0).get("nameParts");
400+
401+
assertNull(ciNode);
402+
403+
JsonNode bankAccountNode =
404+
credentialSubject.get("bankAccount").get(0);
405+
406+
assertEquals(
407+
"11111117", bankAccountNode.get("accountNumber").asText());
408+
assertEquals("204578", bankAccountNode.get("sortCode").asText());
409+
410+
assertEquals("GivenName", nameParts.get(0).get("type").asText());
411+
assertEquals("FamilyName", nameParts.get(1).get("type").asText());
412+
assertEquals("Bob", nameParts.get(0).get("value").asText());
413+
assertEquals("Fossil", nameParts.get(1).get("value").asText());
414+
} catch (VerifiableCredentialException | JsonProcessingException e) {
415+
throw new RuntimeException(e);
416+
}
417+
});
418+
}
419+
308420
@Pact(provider = "BavCriProvider", consumer = "IpvCoreBack")
309421
public RequestResponsePact invalidAccessTokenReturns401(PactDslWithProvider builder) {
310422
return builder.given("dummyApiKey is a valid api key")
@@ -717,4 +829,70 @@ private static OauthCriConfig getMockCredentialIssuerConfig(MockServer mockServe
717829
// change each time we run the tests.
718830
private static final String FAILED_BAV_VC_SIGNATURE =
719831
"JlGnDKxWr2ELrHzh1txDvG21xrINyWQ6fu9gTnoZaWlZzIe5pKrawn9ulwJ2B-0BUvUHMAKURj7sPODiOL-v_w"; // pragma: allowlist secret
832+
833+
private static final String FAILED_BAV_NO_CI_VC_BODY =
834+
"""
835+
{
836+
"nbf": 4070908800,
837+
"iat": 4070908800,
838+
"jti": "jti",
839+
"iss": "dummyBavComponentId",
840+
"sub": "test-subject",
841+
"vc": {
842+
"@context": [
843+
"https://www.w3.org/2018/credentials/v1",
844+
"https://vocab.account.gov.uk/contexts/identity-v1.jsonld"
845+
],
846+
"type": [
847+
"VerifiableCredential",
848+
"IdentityCheckCredential"
849+
],
850+
"credentialSubject": {
851+
"name": [
852+
{
853+
"nameParts": [
854+
{
855+
"type": "GivenName",
856+
"value": "Bob"
857+
},
858+
{
859+
"type": "FamilyName",
860+
"value": "Fossil"
861+
}
862+
]
863+
}
864+
],
865+
"birthDate": [
866+
{
867+
"value": "1960-02-02"
868+
}
869+
],
870+
"bankAccount": [
871+
{
872+
"sortCode": "204578",
873+
"accountNumber": "11111117"
874+
}
875+
]
876+
},
877+
"evidence": [
878+
{
879+
"type": "IdentityCheck",
880+
"strengthScore": 3,
881+
"validityScore": 0,
882+
"failedCheckDetails": [
883+
{
884+
"checkMethod": "data",
885+
"identityCheckPolicy": "none"
886+
}
887+
]
888+
}
889+
]
890+
}
891+
}
892+
""";
893+
// If we generate the signature in code it will be different each time, so we need to generate a
894+
// valid signature (using https://jwt.io works well) and record it here so the PACT file doesn't
895+
// change each time we run the tests.
896+
private static final String FAILED_BAV_NO_CI_VC_SIGNATURE =
897+
"SP4lmGdIwzBanmeQEtwJoBVY7dfBPrFLNnIbNPe8dYYqiqvrqM7KGNgoj5AZK4-QMBdeG6f5wClWb0DcA0cKAg"; // pragma: allowlist secret
720898
}

0 commit comments

Comments
 (0)