UNPKG

meta-capi-param-builder-clientjs

Version:

Conversions API parameter builder for Client-side JavaScript

298 lines (265 loc) 9.89 kB
/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the license found in the * LICENSE file in the root directory of this source tree. */ import { getNormalizedPII } from '../utils/piiUtil/piiUtil.js'; import { PII_DATA_TYPE } from '../model/constants.js'; describe('getNormalizedPII', () => { describe('Input validation', () => { it('should return null for null input', () => { expect(getNormalizedPII(null, PII_DATA_TYPE.EMAIL)).toBeNull(); }); it('should return null for undefined input', () => { expect(getNormalizedPII(undefined, PII_DATA_TYPE.EMAIL)).toBeNull(); }); it('should return null for non-string input', () => { const nonStringValues = [123, {}, [], true, false]; nonStringValues.forEach((value) => { expect(getNormalizedPII(value, PII_DATA_TYPE.EMAIL)).toBeNull(); }); }); it('should return null for empty string input', () => { expect(getNormalizedPII('', PII_DATA_TYPE.EMAIL)).toBeNull(); }); it('should return null for whitespace-only input', () => { expect(getNormalizedPII(' ', PII_DATA_TYPE.EMAIL)).toBeNull(); expect(getNormalizedPII('\t\n\r', PII_DATA_TYPE.EMAIL)).toBeNull(); }); it('should return null for null data type', () => { expect(getNormalizedPII('test@example.com', null)).toBeNull(); }); it('should return null for undefined data type', () => { expect(getNormalizedPII('test@example.com', undefined)).toBeNull(); }); it('should return null for invalid data type', () => { expect(getNormalizedPII('test@example.com', 'invalid_type')).toBeNull(); }); }); describe('Email normalization', () => { it('should normalize valid email addresses', () => { const testCases = [ { input: 'test@example.com', expected: 'test@example.com', }, { input: 'TEST@EXAMPLE.COM', expected: 'test@example.com', }, { input: ' test@example.com ', expected: 'test@example.com', }, { input: '\tTEST@EXAMPLE.COM\n', expected: 'test@example.com', }, { input: 'user.name+tag@domain.co.uk', expected: 'user.name+tag@domain.co.uk', }, { input: 'user123@subdomain.example.org', expected: 'user123@subdomain.example.org', }, { input: 'user_name@example.com', expected: 'user_name@example.com', }, { input: 'user-name@example.com', expected: 'user-name@example.com', }, { input: "test'name@example.com", expected: "test'name@example.com", }, { input: ' John_Smith@gmail.com ', expected: 'john_smith@gmail.com', }, { input: '8df99a46f811595e1a1de5016e2445bc202f72b946482032a75aec528a0a350d', expected: '8df99a46f811595e1a1de5016e2445bc202f72b946482032a75aec528a0a350d', }, { input: 'someone@domain.com', expected: 'someone@domain.com', }, { input: ' SomeOne@domain.com ', expected: 'someone@domain.com', }, ]; testCases.forEach(({ input, expected }) => { expect(getNormalizedPII(input, PII_DATA_TYPE.EMAIL)).toEqual(expected); }); }); it('should return null for invalid email addresses', () => { const invalidEmails = [ 'invalid-email', '@example.com', 'test@', 'test..test@example.com', 'test@example', 'test@example.', 'test @example.com', 'test@exam ple.com', 'plaintext', 'test@@example.com', 'test@.example.com', 'test@example..com', '.test@example.com', 'test.@example.com', 'test@example.com.', ]; invalidEmails.forEach((email) => { const result = getNormalizedPII(email, PII_DATA_TYPE.EMAIL); expect(result).toBeNull(); }); }); it('should handle special characters in valid email addresses', () => { const specialCharEmails = [ 'test+tag@example.com', 'user.name@example.com', 'user_name@example.com', 'user-name@example.com', "test'name@example.com", 'test#name@example.com', 'test$name@example.com', 'test%name@example.com', 'test&name@example.com', 'test*name@example.com', 'test=name@example.com', 'test?name@example.com', 'test^name@example.com', 'test`name@example.com', 'test{name@example.com', 'test|name@example.com', 'test}name@example.com', 'test~name@example.com', ]; specialCharEmails.forEach((email) => { const result = getNormalizedPII(email, PII_DATA_TYPE.EMAIL); expect(result).toEqual(email.toLowerCase()); }); }); it('should handle international domain names', () => { const internationalEmails = [ 'test@example.co.uk', 'test@example.org.au', 'test@subdomain.example.museum', 'test@example.travel', ]; internationalEmails.forEach((email) => { const result = getNormalizedPII(email, PII_DATA_TYPE.EMAIL); expect(result).toEqual(email.toLowerCase()); }); }); it('should handle very long valid email addresses', () => { const longEmail = 'a'.repeat(50) + '@' + 'b'.repeat(50) + '.com'; const result = getNormalizedPII(longEmail, PII_DATA_TYPE.EMAIL); expect(result).toEqual(longEmail.toLowerCase()); }); it('should handle emails with leading/trailing spaces correctly', () => { const testCases = [ { input: ' test@example.com', expected: 'test@example.com', // Trimmed and normalized since valid after trim }, { input: 'test@example.com ', expected: 'test@example.com', // Trimmed and normalized since valid after trim }, { input: ' test@example.com ', expected: 'test@example.com', // Trimmed and normalized since valid after trim }, ]; testCases.forEach(({ input, expected }) => { const result = getNormalizedPII(input, PII_DATA_TYPE.EMAIL); expect(result).toEqual(expected); }); }); }); describe('Hashed email handling', () => { it('should return SHA-256 hash as-is when it looks like a hash', () => { const validHashes = [ 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3', // 'hello' hashed 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', // empty string hashed '2cf24dba4f21d4288094e8452703c0f0142fa00b2eeb1f2c9b4e70f39e8a4c29', // 'hello' in different case 'ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890', // uppercase hash ]; validHashes.forEach((hash) => { const result = getNormalizedPII(hash, PII_DATA_TYPE.EMAIL); expect(result).toEqual(hash); }); }); it('should process invalid hash-like strings as regular emails', () => { const invalidHashes = [ 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae', // 63 chars 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae33', // 65 chars 'g665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3', // invalid char 'g' 'A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE!', // invalid char '!' '', // empty string '123', // too short ]; invalidHashes.forEach((hash) => { const result = getNormalizedPII(hash, PII_DATA_TYPE.EMAIL); // These will be processed as regular emails and likely return null since they're invalid expect(result).toBeNull(); }); }); }); describe('Other PII data types', () => { it('should return null for truly unsupported data types', () => { const unsupportedTypes = ['invalid_type', 'unknown', 'fake_type']; unsupportedTypes.forEach((type) => { expect(getNormalizedPII('test@example.com', type)).toBeNull(); }); }); }); describe('Edge cases with email validation', () => { it('should handle emails with consecutive dots', () => { const consecutiveDotEmails = [ 'test..name@example.com', 'test@example..com', 'test@exam..ple.com', ]; consecutiveDotEmails.forEach((email) => { const result = getNormalizedPII(email, PII_DATA_TYPE.EMAIL); // These should return null since they don't match the regex expect(result).toBeNull(); }); }); it('should handle emails with spaces in the middle', () => { const spacedEmails = [ 'test @example.com', 'test@ example.com', 'test@exam ple.com', ]; spacedEmails.forEach((email) => { const result = getNormalizedPII(email, PII_DATA_TYPE.EMAIL); // These should return null since they don't match the regex after trimming expect(result).toBeNull(); }); }); it('should handle mixed case hashed emails', () => { const mixedCaseHash = 'A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3'; const result = getNormalizedPII(mixedCaseHash, PII_DATA_TYPE.EMAIL); expect(result).toEqual(mixedCaseHash); }); it('should handle lowercase hashed emails', () => { const lowercaseHash = 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3'; const result = getNormalizedPII(lowercaseHash, PII_DATA_TYPE.EMAIL); expect(result).toEqual(lowercaseHash); }); }); });