Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KIWI-2035] - Update name assignment logic #285

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@
"filename": "src/tests/unit/services/ExperianService.test.ts",
"hashed_secret": "640ab2bae07bedc4c163f679a746f7ab7fb5d1fa",
"is_verified": false,
"line_number": 102
"line_number": 103
}
],
"src/tests/unit/services/HmrcTokenRequestProcessor.test.ts": [
Expand Down Expand Up @@ -414,5 +414,5 @@
}
]
},
"generated_at": "2024-11-08T13:43:44Z"
"generated_at": "2024-11-12T11:22:11Z"
}
5 changes: 3 additions & 2 deletions src/services/ExperianService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class ExperianService {

// eslint-disable-next-line max-lines-per-function
async verify(
{ verifyAccountPayload, givenName, surname, birthDate, uuid }: { verifyAccountPayload: any; givenName: string; surname: string; birthDate: string; uuid: string },
{ verifyAccountPayload, firstName, surname, birthDate, uuid }: { verifyAccountPayload: any; firstName: string; surname: string; birthDate: string; uuid: string },
experianUsername: string,
experianPassword: string,
experianClientId: string,
Expand Down Expand Up @@ -82,7 +82,8 @@ export class ExperianService {
},
names: [
{
firstName: givenName,
firstName: firstName,
middleNames: "",
Stelios-CB marked this conversation as resolved.
Show resolved Hide resolved
surName: surname
}
]
Expand Down
4 changes: 2 additions & 2 deletions src/services/PersonInfoRequestProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MessageCodes } from "../models/enums/MessageCodes";
import { EnvironmentVariables } from "../utils/Constants";
import { createDynamoDbClient } from "../utils/DynamoDBFactory";
import { checkEnvironmentVariable } from "../utils/EnvironmentVariables";
import { getNameByType } from "../utils/PersonIdentityUtils";
import { getFullName } from "../utils/PersonIdentityUtils";
import { Response } from "../utils/Response";
import { APIGatewayProxyResult } from "aws-lambda";

Expand Down Expand Up @@ -62,7 +62,7 @@ export class PersonInfoRequestProcessor {
return Response(HttpCodesEnum.UNAUTHORIZED, `No person found with the session id: ${sessionId}`);
}

const name = getNameByType(person.name);
const name = getFullName(person.name);
const encryptedResponseValue = this.encryptResponse({ name });

return Response(HttpCodesEnum.OK, encryptedResponseValue);
Expand Down
26 changes: 13 additions & 13 deletions src/services/VerifyAccountRequestProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { CopCheckResult, ExperianCheckResult, ISessionItem } from "../models/ISe
import { EnvironmentVariables, Constants } from "../utils/Constants";
import { createDynamoDbClient } from "../utils/DynamoDBFactory";
import { checkEnvironmentVariable } from "../utils/EnvironmentVariables";
import { getNameByType } from "../utils/PersonIdentityUtils";
import { getFirstName, getLastName, getFullName } from "../utils/PersonIdentityUtils";
import { Response } from "../utils/Response";
import { buildCoreEventFields } from "../utils/TxmaEvent";
import { VerifyAccountPayload } from "../type/VerifyAccountPayload";
Expand Down Expand Up @@ -109,8 +109,8 @@ export class VerifyAccountRequestProcessor {
return Response(HttpCodesEnum.UNAUTHORIZED, "Too many attempts");
}

const givenName = getNameByType(person.name, "GivenName");
const surname = getNameByType(person.name, "FamilyName");
const firstName = getFirstName(person.name);
const surname = getLastName(person.name);
const birthDate = person.birthDate[0].value;

this.logger.appendKeys({ govuk_signin_journey_id: session.clientSessionId });
Expand All @@ -120,7 +120,7 @@ export class VerifyAccountRequestProcessor {
const coreEventFields = buildCoreEventFields(session, this.issuer, clientIpAddress);

const verifyResponse = await this.ExperianService.verify(
{ verifyAccountPayload, givenName, surname, birthDate, uuid: vendorUuid },
{ verifyAccountPayload, firstName, surname, birthDate, uuid: vendorUuid },
ssmParams.experianUsername,
ssmParams.experianPassword,
ssmParams.experianClientId,
Expand All @@ -143,20 +143,20 @@ export class VerifyAccountRequestProcessor {
evidence: [
{
txn: verifyResponse?.expRequestId,
attemptNum: session.attemptCount ?? 1,
},
],
},
restricted: {
Experian_request_details: [
{
name:`${givenName} ${surname}`,
sortCode: verifyAccountPayload?.sort_code,
accountNumber: verifyAccountPayload?.account_number,
attemptNum: session.attemptCount ?? 1,
},
],
name: person.name,
Stelios-CB marked this conversation as resolved.
Show resolved Hide resolved
birthDate: person.birthDate,
bankAccount: [{
sortCode: verifyAccountPayload?.sort_code,
accountNumber: verifyAccountPayload?.account_number,
}],
},
}, encodedHeader);


await this.BavService.sendToTXMA(this.txmaQueueUrl, {
event_name: TxmaEventNames.BAV_EXPERIAN_RESPONSE_RECEIVED,
Expand Down Expand Up @@ -211,7 +211,7 @@ export class VerifyAccountRequestProcessor {
return Response(HttpCodesEnum.UNAUTHORIZED, "Too many attempts");
}

const name = getNameByType(person.name);
const name = getFullName(person.name);
this.logger.appendKeys({ govuk_signin_journey_id: session.clientSessionId });
const timeOfRequest = absoluteTimeNow();

Expand Down
14 changes: 7 additions & 7 deletions src/tests/unit/services/ExperianService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const experianPayload = {
names: [
{
firstName: "First",
middleNames: "",
surName: "Last",
},
],
Expand Down Expand Up @@ -121,9 +122,8 @@ describe("Experian service", () => {
account_number: "12345678",
sort_code: "123456",
};
const accountNumber = "12345678";
const sortCode = "123456";
const givenName = "First";

const firstName = "First";
const surname = "Last";
const uuid = "uuid";
const birthDate = "DATE";
Expand All @@ -135,7 +135,7 @@ describe("Experian service", () => {

mockDynamoDbClient.send = jest.fn().mockResolvedValue({ Item: storedExperianToken });

const response = await experianServiceTest.verify({ verifyAccountPayload, givenName, surname, birthDate, uuid },
const response = await experianServiceTest.verify({ verifyAccountPayload, firstName, surname, birthDate, uuid },
clientUsername,
clientPassword,
clientId,
Expand Down Expand Up @@ -179,7 +179,7 @@ describe("Experian service", () => {

mockDynamoDbClient.send = jest.fn().mockResolvedValue({ Item: storedExperianToken });

const response = await experianServiceTest.verify({ verifyAccountPayload, givenName, surname, birthDate, uuid },
const response = await experianServiceTest.verify({ verifyAccountPayload, firstName, surname, birthDate, uuid },
clientUsername,
clientPassword,
clientId,
Expand Down Expand Up @@ -220,7 +220,7 @@ describe("Experian service", () => {
jest.spyOn(axios, "post").mockResolvedValueOnce({ data: errorResponse });
mockDynamoDbClient.send = jest.fn().mockResolvedValueOnce({ Item: storedExperianToken });

await experianServiceTest.verify({ verifyAccountPayload, givenName, surname, birthDate, uuid }, clientUsername,
await experianServiceTest.verify({ verifyAccountPayload, firstName, surname, birthDate, uuid }, clientUsername,
clientPassword,
clientId,
clientSecret,
Expand All @@ -239,7 +239,7 @@ describe("Experian service", () => {
jest.spyOn(axios, "post").mockResolvedValueOnce({ data: errorResponse });
mockDynamoDbClient.send = jest.fn().mockResolvedValueOnce({ Item: storedExperianToken });

await experianServiceTest.verify({ verifyAccountPayload, givenName, surname, birthDate, uuid }, clientUsername,
await experianServiceTest.verify({ verifyAccountPayload, firstName, surname, birthDate, uuid }, clientUsername,
clientPassword,
clientId,
clientSecret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ describe("VerifyAccountRequestProcessor", () => {
ssmParams,
);

expect(mockExperianService.verify).toHaveBeenCalledWith({ verifyAccountPayload, birthDate: "12-01-1986", givenName: "Frederick Joseph", surname: "Flintstone", uuid: vendorUuid },
expect(mockExperianService.verify).toHaveBeenCalledWith({ verifyAccountPayload, birthDate: "12-01-1986", firstName: "Frederick", surname: "Flintstone", uuid: vendorUuid },
"123456",
"12345678",
"clientId",
Expand All @@ -230,19 +230,18 @@ describe("VerifyAccountRequestProcessor", () => {
evidence: [
{
txn: "1234568",
attemptNum: 1,
},
],
},
restricted:{
"Experian_request_details": [
{
name: "Frederick Joseph Flintstone",
sortCode: verifyAccountPayload.sort_code,
accountNumber: verifyAccountPayload.account_number,
attemptNum: 1,
},
],
},
restricted: {
name: person.name,
birthDate: person.birthDate,
bankAccount: [{
sortCode: verifyAccountPayload.sort_code,
accountNumber: verifyAccountPayload.account_number,
}],
},
timestamp: 1585695600,
event_timestamp_ms: 1585695600000,
user: {
Expand Down Expand Up @@ -292,7 +291,7 @@ describe("VerifyAccountRequestProcessor", () => {
{ sessionId, accountNumber: "12345678", sortCode: verifyAccountPayload.sort_code },
process.env.PERSON_IDENTITY_TABLE_NAME,
);
expect(mockExperianService.verify).toHaveBeenCalledWith({ verifyAccountPayload, birthDate: "12-01-1986", givenName: "Frederick Joseph", surname: "Flintstone", uuid: vendorUuid },
expect(mockExperianService.verify).toHaveBeenCalledWith({ verifyAccountPayload, birthDate: "12-01-1986", firstName: "Frederick", surname: "Flintstone", uuid: vendorUuid },
"123456",
"12345678",
"clientId",
Expand Down
85 changes: 57 additions & 28 deletions src/tests/unit/utils/PersonIdentityUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
import { getNameByType } from "../../../utils/PersonIdentityUtils";
import { getFirstName, getMiddleNames, getLastName, getFullName } from "../../../utils/PersonIdentityUtils";

describe("PersonIdentityUtils", () => {
describe("#getNameByType", () => {
it("returns all full name if no name type provided", () => {
const result = getNameByType([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "Middle" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("First Middle Last");
});

it("returns name based on type - GivenName", () => {
const result = getNameByType([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "Middle" },
{ type: "FamilyName", value: "Last" },
] }], "GivenName");
expect(result).toBe("First Middle");
});

it("returns name based on type - FamilyName", () => {
const result = getNameByType([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "Middle" },
{ type: "FamilyName", value: "Last" },
] }], "FamilyName");
expect(result).toBe("Last");
});

it("returns all full name", () => {
const result = getFullName([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "Middle" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("First Middle Last");
});

it("returns first name", () => {
const result = getFirstName([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "Middle" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("First");
});


it("returns middle name", () => {
const result = getMiddleNames([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "Middle" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("Middle");
});

it("returns multiple middle names", () => {
const result = getMiddleNames([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "MiddleOne" },
{ type: "GivenName", value: "MiddleTwo" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("MiddleOne MiddleTwo");
});

it("returns empty string if no middle names provided", () => {
const result = getMiddleNames([{ nameParts: [
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("");
});

it("returns last name", () => {
const result = getLastName([{ nameParts: [
Stelios-CB marked this conversation as resolved.
Show resolved Hide resolved
{ type: "GivenName", value: "First" },
{ type: "GivenName", value: "MiddleOne" },
{ type: "GivenName", value: "MiddleTwo" },
{ type: "FamilyName", value: "Last" },
] }]);
expect(result).toBe("Last");
});

});
28 changes: 26 additions & 2 deletions src/utils/PersonIdentityUtils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
import { PersonIdentityName } from "../models/PersonIdentityItem";

export const getNameByType = (name: PersonIdentityName[], targetType?: string): string => {
export const getFirstName = (name: PersonIdentityName[]): string => {
return name[0]?.nameParts[0].value;
};

export const getMiddleNames = (name: PersonIdentityName[]): string => {
const nameParts = name[0]?.nameParts
.filter((part) => part.type === "GivenName")
.slice(1)
.reduce((nameArray: string[], { value }) => {
nameArray.push(value);
return nameArray;
}, []) || [];
return nameParts.join(" ");
};

export const getLastName = (name: PersonIdentityName[]): string => {
const nameParts = name[0]?.nameParts
.filter((part) => part.type === "FamilyName")
.reduce((nameArray: string[], { value }) => {
nameArray.push(value);
return nameArray;
}, []) || [];
return nameParts.join(" ");
};

export const getFullName = (name: PersonIdentityName[]): string => {
const nameParts = name[0]?.nameParts
.filter((part) => !targetType || part.type === targetType) // Filter if targetType is provided
.reduce((nameArray: string[], { value }) => {
nameArray.push(value);
return nameArray;
Expand Down
Loading