-
Notifications
You must be signed in to change notification settings - Fork 122
feat: adds tools for handling brazilian passports #469
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
Merged
hyanmandian
merged 10 commits into
brazilian-utils:main
from
vicentevendramin:feat/adds-tools-for-handling-brazilian-passports
Apr 7, 2026
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
f4e7a90
feat: add Brazilian passport validation utilities
vicentevendramin b4df189
test: add unit tests for passport utilities
vicentevendramin 1e3deaa
fix: replace as any with as unknown as string in test
vicentevendramin 5f90a74
refactor: split passport functions into separate modules
vicentevendramin cbca9e6
docs: add documentation for passport utilities
vicentevendramin f4dced0
refactor: apply code review suggestions for passport module
vicentevendramin 86e37cf
fix: lint
vicentevendramin 14d186e
chore: rebase and resolve conflicts with main
vicentevendramin ca8c368
fix: passport tests
vicentevendramin da4e356
fix: lint
vicentevendramin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import { describe, expect, test } from "../_internals/test/runtime"; | ||
| import { formatPassport } from "./format-passport"; | ||
|
|
||
| describe("formatPassport", () => { | ||
| describe("should return the formatted passport", () => { | ||
| test("when passport is valid", () => { | ||
| expect(formatPassport("AB123456")).toBe("AB123456"); | ||
| }); | ||
|
|
||
| test("when passport has lowercase letters", () => { | ||
| expect(formatPassport("acd12736")).toBe("ACD12736"); | ||
| }); | ||
| }); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| /** | ||
| * Formats a Brazilian passport number for display. | ||
| * Converts to uppercase and removes all non-alphanumeric characters. | ||
| * | ||
| * @param passport - A Brazilian passport number (any case, possibly with symbols). | ||
| * @returns The formatted passport number (uppercase, no symbols), or an empty string if invalid. | ||
| * | ||
| * @example | ||
| * formatPassport("ab123456") // "AB123456" | ||
| * formatPassport("AB-123.456") // "AB123456" | ||
| * formatPassport("") // "" | ||
| */ | ||
| export const formatPassport = (passport: string): string => { | ||
| if (!passport || typeof passport !== "string") return ""; | ||
| return passport.toUpperCase().replace(/[^A-Z0-9]/g, ""); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| export const LETTERS_LENGTH = 2; | ||
| export const DIGITS_LENGTH = 6; | ||
| export const ALPHABET_LENGTH = 26; | ||
| export const CHAR_CODE_A = 65; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { describe, expect, test } from "../_internals/test/runtime"; | ||
| import { isValidPassport } from "../is-valid-passport/is-valid-passport"; | ||
| import { generatePassport } from "./generate-passport"; | ||
|
|
||
| describe("generatePassport", () => { | ||
| test("should always generate a valid passport", () => { | ||
| for (let i = 0; i < 100; i++) { | ||
| expect(isValidPassport(generatePassport())).toBe(true); | ||
| } | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import { generateRandomNumber } from "../_internals/generate-random-number/generate-random-number"; | ||
| import { ALPHABET_LENGTH, CHAR_CODE_A, DIGITS_LENGTH, LETTERS_LENGTH } from "./constants"; | ||
|
|
||
| /** | ||
| * Generates a random valid Brazilian passport number. | ||
| * | ||
| * @returns A random valid passport number string (e.g. "RY393097"). | ||
| * | ||
| * @example | ||
| * generatePassport() // "RY393097" | ||
| * generatePassport() // "ZS840088" | ||
| */ | ||
| export const generatePassport = (): string => { | ||
| const letters = Array.from({ length: LETTERS_LENGTH }, () => | ||
| String.fromCharCode(CHAR_CODE_A + Math.floor(Math.random() * ALPHABET_LENGTH)), | ||
| ).join(""); | ||
|
|
||
| const digits = generateRandomNumber(DIGITS_LENGTH); | ||
|
|
||
| return `${letters}${digits}`; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const PASSPORT_REGEX = /^[A-Z]{2}[0-9]{6}$/; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { describe, expect, test } from "../_internals/test/runtime"; | ||
| import { isValidPassport } from "./is-valid-passport"; | ||
|
|
||
| describe("isValidPassport", () => { | ||
| describe("should return false", () => { | ||
| test("when passport is not a string", () => { | ||
| expect(isValidPassport(1 as unknown as string)).toBe(false); | ||
| }); | ||
|
|
||
| test("when passport length is different from 8", () => { | ||
| expect(isValidPassport("1")).toBe(false); | ||
| }); | ||
|
|
||
| test("when passport does not match the expected format", () => { | ||
| expect(isValidPassport("1112223334-")).toBe(false); | ||
| }); | ||
| }); | ||
|
|
||
| describe("should return true", () => { | ||
| test("when passport is valid", () => { | ||
| expect(isValidPassport("AA111111")).toBe(true); | ||
| expect(isValidPassport("CL125167")).toBe(true); | ||
| }); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import { PASSPORT_REGEX } from "./constants"; | ||
|
|
||
| /** | ||
| * Checks if a Brazilian passport number is valid. | ||
| * To be considered valid, the input must be a string containing exactly two | ||
| * alphabetical characters followed by exactly six numerical digits. | ||
| * This function does not verify if the input is a real passport number, | ||
| * as there are no checksums for the Brazilian passport. | ||
| * | ||
| * @param passport - The string containing the passport number to be checked. | ||
| * @returns True if the passport number is valid (2 letters followed by 6 digits). | ||
| * | ||
| * @example | ||
| * isValidPassport("Ab123456") // false - must be uppercase | ||
| * isValidPassport("AB123456") // true | ||
| * isValidPassport("12345678") // false | ||
| * isValidPassport("DC-221345") // false | ||
| */ | ||
| export const isValidPassport = (passport: string | number): boolean => { | ||
| if (passport === null || passport === undefined) return false; | ||
| return PASSPORT_REGEX.test(String(passport)); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { describe, expect, test } from "../_internals/test/runtime"; | ||
| import { parsePassport } from "./parse-passport"; | ||
|
|
||
| describe("parsePassport", () => { | ||
| describe("should return the string without symbols", () => { | ||
| test("when there are no symbols, returns the same string", () => { | ||
| expect(parsePassport("Ab123456")).toBe("Ab123456"); | ||
| }); | ||
|
|
||
| test("when there are spaces", () => { | ||
| expect(parsePassport(" AB 123 456 ")).toBe("AB123456"); | ||
| }); | ||
|
|
||
| test("when there are dashes", () => { | ||
| expect(parsePassport("-AB1-23-4-56-")).toBe("AB123456"); | ||
| }); | ||
|
|
||
| test("when there are dots", () => { | ||
| expect(parsePassport(".AB.1.23.456.")).toBe("AB123456"); | ||
| }); | ||
|
|
||
| test("when there are multiple symbols", () => { | ||
| expect(parsePassport(".A B.1.2-3.45 -. 6.")).toBe("AB123456"); | ||
| }); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| /** | ||
| * Removes symbols ('-', '.', and whitespaces) from a passport number. | ||
| * | ||
| * @param passport - The string containing a passport number. | ||
| * @returns The passport number with dashes, dots, and whitespaces removed. | ||
| * | ||
| * @example | ||
| * parsePassport("Ab123456") // "Ab123456" | ||
| * parsePassport("Ab-123456") // "Ab123456" | ||
| * parsePassport("Ab -. 123456") // "Ab123456" | ||
| */ | ||
| export const parsePassport = (passport: string): string => { | ||
| if (!passport || typeof passport !== "string") return ""; | ||
| return passport.replace(/[^a-zA-Z0-9]/g, ""); | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tem como tu tirar o mock aqui?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removi o mock e alterei o
formatPassport