Compare commits

...

2 Commits

Author SHA1 Message Date
9e53756551 Add validation and tests for NLC and STANOX
All checks were successful
Testing / run-tests (push) Successful in 3m13s
2025-03-13 20:25:14 +00:00
0aca569c31 Add tests for custom error classes 2025-03-13 20:24:54 +00:00
3 changed files with 132 additions and 2 deletions

32
src/errors.test.ts Normal file
View File

@ -0,0 +1,32 @@
import { ApiError, ValidationError, NetworkError } from "./errors";
describe("Custom Error Class Tests", () => {
test("ApiError should store message, statusCode and responseBody", () => {
const error = new ApiError("API Request failed", 404, "Not Found");
expect(error).toBeInstanceOf(ApiError);
expect(error).toBeInstanceOf(Error);
expect(error.name).toBe("ApiError");
expect(error.message).toBe("API Request failed");
expect(error.statusCode).toBe(404);
expect(error.responseBody).toBe("Not Found");
})
test("ValidationError should store message", () => {
const error = new ValidationError("Invalid input");
expect(error).toBeInstanceOf(ValidationError);
expect(error).toBeInstanceOf(Error);
expect(error.name).toBe("ValidationError");
expect(error.message).toBe("Invalid input");
})
test("NetworkError should store message", () => {
const error = new NetworkError("Network Unreachable");
expect(error).toBeInstanceOf(NetworkError);
expect(error).toBeInstanceOf(Error);
expect(error.name).toBe("NetworkError");
expect(error.message).toBe("Network Unreachable");
})
})

View File

@ -4,7 +4,9 @@ import { validateCrs,
validateReasonCode,
validateTiploc,
validateUuid,
validateHeadcode } from "./inputValidation";
validateHeadcode,
validateNlc,
validateStanox} from "./inputValidation";
import { ValidationError } from "../errors";
describe("PIS Validation Tests", () => {
@ -59,6 +61,65 @@ describe("CRS Validation Tests", () => {
})
})
describe("NLC Validation Tests", () => {
test("NLC inputs that are valid should return true", () => {
expect(validateNlc(354300)).toBe(true);
expect(validateNlc("322962")).toBe(true);
expect(validateNlc(999999)).toBe(true);
expect(validateNlc("999999")).toBe(true);
expect(validateNlc(100000)).toBe(true);
expect(validateNlc("100000")).toBe(true);
})
test("NLC inputs that are out of range should throw ValidationError", () => {
expect(() => validateNlc(3543)).toThrow(ValidationError);
expect(() => validateNlc("3229")).toThrow(ValidationError);
expect(() => validateNlc(3543001)).toThrow(ValidationError);
expect(() => validateNlc("3543001")).toThrow(ValidationError);
expect(() => validateNlc(99999)).toThrow(ValidationError);
expect(() => validateNlc(1000001)).toThrow(ValidationError);
expect(() => validateNlc("99999")).toThrow(ValidationError);
expect(() => validateNlc("1000001")).toThrow(ValidationError);
})
test("NLC inputs that are not numeric should throw ValidationError", () => {
expect(() => validateNlc([])).toThrow(ValidationError);
expect(() => validateNlc({})).toThrow(ValidationError);
expect(() => validateNlc(null)).toThrow(ValidationError);
expect(() => validateNlc(undefined)).toThrow(ValidationError);
expect(() => validateNlc(false)).toThrow(ValidationError);
expect(() => validateNlc("3543ab")).toThrow(ValidationError);
})
})
describe("STANOX Validation Tests", () => {
test("STANOX inputs of the correct format should return true", () => {
expect(validateStanox(11234)).toBe(true);
expect(validateStanox("11234")).toBe(true);
expect(validateStanox("99999")).toBe(true);
expect(validateStanox(10000)).toBe(true);
expect(validateStanox("10000")).toBe(true);
expect(validateStanox("01234")).toBe(true);
})
test("STANOX inputs that are out of range should throw Validation Error", () => {
expect(() => validateStanox(9999)).toThrow(ValidationError);
expect(() => validateStanox("9999")).toThrow(ValidationError);
expect(() => validateStanox(0o1234)).toThrow(ValidationError);
expect(() => validateStanox("100000")).toThrow(ValidationError);
expect(() => validateStanox(100000)).toThrow(ValidationError);
})
test("STANOX inputs that are not numeric should throw ValidationError", () => {
expect(() => validateStanox([])).toThrow(ValidationError);
expect(() => validateStanox({})).toThrow(ValidationError);
expect(() => validateStanox(null)).toThrow(ValidationError);
expect(() => validateStanox(undefined)).toThrow(ValidationError);
expect(() => validateStanox(false)).toThrow(ValidationError);
expect(() => validateStanox("3543ab")).toThrow(ValidationError);
})
})
describe("UUID Validation Tests", () => {
test("UUID inputs that are valid v4-UUIDs should return true", () => {
expect(validateUuid("5c5db50b-91c8-440c-80af-afc7bb375b4b")).toBe(true);

View File

@ -38,6 +38,42 @@ export function validateCrs(crs: unknown): boolean {
return true;
}
export function validateNlc(nlc: unknown): boolean {
if (typeof nlc === "string") {
if (!/^\d{6}$/.test(nlc)) {
throw new ValidationError("Invalid input: NLC must be a 6 digit number (or a string representation)");
}
return true;
}
if (typeof nlc === "number") {
if (!Number.isInteger(nlc) || nlc < 100000 || nlc > 999999) {
throw new ValidationError("Invalid input: NLC must be a 6 digit number (or a string representation)");
}
return true;
}
// If not a string or number, throw ValidationError
throw new ValidationError("Invalid input: NLC must be a 6 digit number (or string representation");
}
export function validateStanox(stanox: unknown): boolean {
if (typeof stanox === "string") {
if (!/^\d{5}$/.test(stanox)) {
throw new ValidationError("Invalid input: STANOX must be a 5 digit number (or a string representation)");
}
return true;
}
if (typeof stanox === "number") {
if (!Number.isInteger(stanox) || stanox < 10000 || stanox > 99999) {
throw new ValidationError("Invalid input: STANOX must be a 5 digit number (or a string representation");
}
return true;
}
// If not a string or number, throw ValidationError
throw new ValidationError("Invalid input: STANOX must be a 5 digit numer (or a string representation)");
}
export function validateUuid(uuid: unknown): boolean {
if (typeof uuid !== "string") {
throw new ValidationError("Invalid input: The UUID/api_key should be a string");
@ -78,4 +114,5 @@ export function validateHeadcode(headcode: unknown): boolean {
throw new ValidationError("Invalid input: Headcode must be in the format dLdd where d=digit and L=letter");
}
return true;
}
}