Skip to content

Commit 2b9d217

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 2b9d217

File tree

1 file changed

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

1 file changed

+180
-0
lines changed

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

+180
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import static org.hamcrest.MatcherAssert.assertThat;
5858
import static org.hamcrest.Matchers.greaterThan;
5959
import static org.junit.jupiter.api.Assertions.assertEquals;
60+
import static org.junit.jupiter.api.Assertions.assertNull;
6061
import static org.junit.jupiter.api.Assertions.assertThrows;
6162
import static org.mockito.ArgumentMatchers.any;
6263
import static org.mockito.Mockito.when;
@@ -305,6 +306,119 @@ void fetchVerifiableCredential_whenCalledAgainstBavCri_retrievesAVcWithACi(
305306
});
306307
}
307308

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

0 commit comments

Comments
 (0)