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

fix(IT Wallet): [SIW-1834] Refactor date claim parser #6431

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
133 changes: 133 additions & 0 deletions ts/features/itwallet/common/utils/__tests__/itwClaimsUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import MockDate from "mockdate";
import * as O from "fp-ts/lib/Option";
import * as E from "fp-ts/lib/Either";
import {
DateWithoutTimezoneClaim,
extractFiscalCode,
getCredentialExpireDate,
getCredentialExpireDays,
Expand Down Expand Up @@ -468,3 +469,135 @@ describe("getCredentialStatus", () => {
});
});
});

describe("DateWithoutTimezoneClaim", () => {
it("should decode a valid date string without timezone", () => {
const input = "2024-11-19"; // Data valida in formato YYYY-MM-DD
const result = DateWithoutTimezoneClaim.decode(input);
expect(E.isRight(result)).toBe(true);
if (E.isRight(result)) {
const decodedDate = result.right;
expect(decodedDate.getUTCFullYear()).toBe(2024);
expect(decodedDate.getUTCMonth()).toBe(10);
expect(decodedDate.getUTCDate()).toBe(19);
expect(decodedDate.toISOString()).toBe("2024-11-19T00:00:00.000Z");
}
});

it("should fail decoding an invalid date string", () => {
const input = "19-11-2024"; // Data in formato non valido
const result = DateWithoutTimezoneClaim.decode(input);
expect(E.isLeft(result)).toBe(true);
});

it("should fail decoding a completely invalid input", () => {
const invalidInput = 123456789;
const result = DateWithoutTimezoneClaim.decode(invalidInput);
expect(E.isLeft(result)).toBe(true);
});

test("should serialize a Date instance to a valid date string without timezone", () => {
const input = new Date(Date.UTC(2024, 10, 19));
const result = DateWithoutTimezoneClaim.encode(input);

expect(result).toBe("2024-11-19");
});

test("should validate and transform a string with leading zeros in the month/day", () => {
const input = "2024-01-05"; // Data con zeri iniziali
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(true);
if (E.isRight(result)) {
const date = result.right;
expect(date).toBeInstanceOf(Date);
expect(date.toISOString()).toBe("2024-01-05T00:00:00.000Z");
}
});

test("should validate a date string with the last day of the year", () => {
const input = "2024-12-31"; // Ultimo giorno dell'anno
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(true);
if (E.isRight(result)) {
const date = result.right;
expect(date.toISOString()).toBe("2024-12-31T00:00:00.000Z");
}
});

test("should validate a leap year date (February 29)", () => {
const input = "2024-02-29"; // Anno bisestile
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(true);
if (E.isRight(result)) {
const date = result.right;
expect(date.toISOString()).toBe("2024-02-29T00:00:00.000Z");
}
});

test("should validate a string representing January 1st", () => {
const input = "2024-01-01"; // Primo giorno dell'anno
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(true);
if (E.isRight(result)) {
const date = result.right;
expect(date.toISOString()).toBe("2024-01-01T00:00:00.000Z");
}
});

test("should fail for empty string input", () => {
const input = ""; // Stringa vuota
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(false);
if (E.isRight(result) === false) {
expect(result.left[0].message).toBe("Date is not in the correct format");
}
});

test("should fail for a string with invalid characters", () => {
const input = "2024-11-abc"; // Input con caratteri non validi
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(false);
if (E.isRight(result) === false) {
expect(result.left[0].message).toBe("Date is not in the correct format");
}
});

test("should fail if the year is less than four digits", () => {
const input = "24-11-19"; // Anno non valido
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(false);
if (E.isRight(result) === false) {
expect(result.left[0].message).toBe("Date is not in the correct format");
}
});

test("should fail if the year exceeds reasonable bounds", () => {
const input = "10000-01-01"; // Anno troppo grande
const result = DateWithoutTimezoneClaim.decode(input);

expect(E.isRight(result)).toBe(false);
if (E.isRight(result) === false) {
expect(result.left[0].message).toBe("Date is not in the correct format");
}
});

test("should serialize and deserialize a Date instance correctly", () => {
const input = new Date(Date.UTC(2024, 10, 19)); // 19 Novembre 2024
const encoded = DateWithoutTimezoneClaim.encode(input);
expect(encoded).toBe("2024-11-19");

const decoded = DateWithoutTimezoneClaim.decode(encoded);
expect(E.isRight(decoded)).toBe(true);
if (E.isRight(decoded)) {
const date = decoded.right;
expect(date.toISOString()).toBe("2024-11-19T00:00:00.000Z");
}
});
});
ale-mazz marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 6 additions & 3 deletions ts/features/itwallet/common/utils/itwClaimsUtils.ts
ale-mazz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import I18n from "../../../../i18n";
import { removeTimezoneFromDate } from "../../../../utils/dates";
import { JsonFromString } from "./ItwCodecUtils";
import {
ItwCredentialStatus,
ParsedCredential,
StoredCredential,
ItwCredentialStatus
StoredCredential
} from "./itwTypesUtils";

/**
Expand Down Expand Up @@ -193,7 +193,10 @@ export const DateWithoutTimezoneClaim = new t.Type<Date, string, unknown>(
)
),
(date: Date) =>
`${date.getUTCFullYear()}-${date.getUTCMonth()}-${date.getUTCDate()}`
`${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(
2,
"0"
)}-${String(date.getUTCDate()).padStart(2, "0")}`
);

/**
Expand Down
3 changes: 2 additions & 1 deletion ts/utils/__tests__/dates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,12 @@ describe("getDateFromExpiryDate", () => {

describe("removeTimezoneFromDate", () => {
it("should remove the timezone from a date", () => {
const date = new Date("2023-02-01");
const date = new Date("2023-02-01T12:00:00-05:00");
const dateWithoutTimezone = removeTimezoneFromDate(date);
expect(dateWithoutTimezone.getDate()).toBe(1);
expect(dateWithoutTimezone.getMonth()).toBe(1); // Month is zero based
expect(dateWithoutTimezone.getFullYear()).toBe(2023);
expect(dateWithoutTimezone.toISOString()).toBe("2023-02-01T00:00:00.000Z");
});

it("should throw if the date is invalid", () => {
Expand Down
7 changes: 4 additions & 3 deletions ts/utils/dates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,11 @@ export const getDateFromExpiryDate = (expiryDate: string): Date | undefined => {
* @param date - the date to remove timezone from
* @returns a new date with the timezone removed
*/
export const removeTimezoneFromDate = (date: Date) => {
export const removeTimezoneFromDate = (date: Date): Date => {
if (isNaN(date.getTime())) {
throw new Error("Invalid date");
}
const userTimezoneOffset = date.getTimezoneOffset() * 60000;
return new Date(date.getTime() + userTimezoneOffset);
return new Date(
Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
);
ale-mazz marked this conversation as resolved.
Show resolved Hide resolved
};
Loading