UNPKG

nigerian-mobile-validator

Version:

The most rigorous, up-to-date library for validating Nigerian mobile numbers. Fully NCC-compliant, and security-focused, with enterprise-grade features to prevent the business risks of validation failures in regulated industries.

220 lines (219 loc) 11.1 kB
"use strict"; // src/__tests__/synthetic-data/test-data-generator-base.ts var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TestDataGeneratorBase = void 0; const network_access_code_1 = require("../../numbering-plan/network-access-code"); const telco_1 = require("../../numbering-plan/telco"); const chance_1 = __importDefault(require("chance")); // Initialize Chance with a seed for reproducibility if needed const chance = new chance_1.default(); /** * Base class with common test data generation functionality */ class TestDataGeneratorBase { /** * Initialize the mappings of telcos to network codes */ static initialize() { if (this.initialized) return; // Create record with empty arrays for each Telco Object.values(telco_1.Telco).forEach(telco => { this._networkCodesByTelco[telco] = []; }); // Populate based on the explicit mapping Object.entries(this.networkCodeToTelcoMap).forEach(([codeKey, telco]) => { // The key is the enum name (e.g., "703"), but we need to convert to the enum value const networkCode = Number(codeKey); // Skip invalid telcos && Skip 702 for special handling if (!telco_1.invalidTelcos.includes(telco) && networkCode !== network_access_code_1.NetworkAccessCode.n702) { // This is an actively used network code - add it to the telco's list this._networkCodesByTelco[telco].push(networkCode); // Also add it to the overall valid network codes list if (!this._allValidNetworkCodes.includes(networkCode)) { this._allValidNetworkCodes.push(networkCode); } } }); // Special handling for 702 - add to multiple telcos due to sub-ranges this._networkCodesByTelco[telco_1.Telco.Smile].push(network_access_code_1.NetworkAccessCode.n702); this._networkCodesByTelco[telco_1.Telco.InterconnectClearinghouse].push(network_access_code_1.NetworkAccessCode.n702); this._networkCodesByTelco[telco_1.Telco.Openskys].push(network_access_code_1.NetworkAccessCode.n702); this._networkCodesByTelco[telco_1.Telco.Visafone].push(network_access_code_1.NetworkAccessCode.n702); this._networkCodesByTelco[telco_1.Telco.Withdrawn].push(network_access_code_1.NetworkAccessCode.n702); this._networkCodesByTelco[telco_1.Telco.Returned].push(network_access_code_1.NetworkAccessCode.n702); // Flatten all valid network codes and deduplicate this._allValidNetworkCodes = Object.values(this._networkCodesByTelco) .flat() .filter((value, index, self) => self.indexOf(value) === index); this._allValidTelcos = Object.values(telco_1.Telco).filter((telco) => !telco_1.invalidTelcos.includes(telco)); this.initialized = true; } /** * Valid Nigerian mobile network codes grouped by telco */ static get networkCodesByTelco() { this.initialize(); return this._networkCodesByTelco; } /** * Valid network codes for any Nigerian mobile number */ static get allValidNetworkCodes() { this.initialize(); return this._allValidNetworkCodes; } /** * Valid Telcos for any Nigerian mobile numbering plan */ static get allValidTelcos() { this.initialize(); return this._allValidTelcos; } /** * Generate a random subscriber number appropriate for the given network code * @param networkCode Optional network code to generate a suitable subscriber number for * @returns A valid subscriber number as a string */ static randomSubscriberNumber(networkCode) { // Special handling for 702 network code which has multiple sub-ranges if (networkCode === network_access_code_1.NetworkAccessCode.n702) { // Use the existing method for 702 subscriber numbers // Get all operators from specialCase702 and filter only valid ones const allOperators = Object.keys(this.specialCase702); // Filter out withdrawn and returned ranges const validOperators = allOperators.filter(op => !op.startsWith('Withdrawn') && op !== 'Returned'); const selectedOperator = chance.pickone(validOperators); return TestDataGeneratorBase.random702SubscriberNumber(selectedOperator); } // For all other network codes, generate a standard 7-digit number return chance.string({ length: 7, pool: '0123456789' }); } /** * Generate a subscriber number for a specific operator in the 702 range */ static random702SubscriberNumber(operator) { const range = this.specialCase702[operator]; const subscriberNumber = chance.integer({ min: range.min, max: range.max }); return subscriberNumber.toString().padStart(7, '0'); } /** * Get a random valid network code for a specific telco */ static randomNetworkCodeForTelco(telco) { var _a; this.initialize(); if (telco_1.invalidTelcos.includes(telco)) { throw new Error(`Invalid Telcos cannot be used when selecting random network codes. Telco name: ${telco}`); } const codes = (_a = TestDataGeneratorBase.networkCodesByTelco[telco]) !== null && _a !== void 0 ? _a : []; if (codes.length == 0) throw new Error(`Unexpected error: this telco (${telco}) has no network codes`); return chance.pickone(codes); } /** * Get a random valid network code */ static randomNetworkCode() { this.initialize(); return chance.pickone(TestDataGeneratorBase.allValidNetworkCodes); } /** * Get a random invalid network code */ static randomInvalidNetworkCode() { return chance.pickone(TestDataGeneratorBase.invalidNetworkCodes); } /** * Shuffle an array using Fisher-Yates algorithm */ static shuffleArray(array) { const result = [...array]; for (let i = result.length - 1; i > 0; i--) { // eslint-disable-next-line security-node/detect-insecure-randomness const j = Math.floor(Math.random() * (i + 1)); [result[i], result[j]] = [result[j], result[i]]; } return result; } } exports.TestDataGeneratorBase = TestDataGeneratorBase; /** * Explicit mapping of network codes to telcos. * This provides an independent reference for testing that doesn't * rely on the same logic used in the production code. * * Note: This mapping is based on the NCC documents but maintained * separately from the production code to ensure test independence. */ TestDataGeneratorBase.networkCodeToTelcoMap = { [network_access_code_1.NetworkAccessCode.n700]: telco_1.Telco.SharedVAS, [network_access_code_1.NetworkAccessCode.n701]: telco_1.Telco.Airtel, // 702 is handled specially for its sub-ranges [network_access_code_1.NetworkAccessCode.n703]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n704]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n705]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n706]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n707]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n708]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n709]: telco_1.Telco.Withdrawn, [network_access_code_1.NetworkAccessCode.n710]: telco_1.Telco.Telewyz, [network_access_code_1.NetworkAccessCode.n800]: telco_1.Telco.SharedVAS, [network_access_code_1.NetworkAccessCode.n801]: telco_1.Telco.Mafab, [network_access_code_1.NetworkAccessCode.n802]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n803]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n804]: telco_1.Telco.MTel, [network_access_code_1.NetworkAccessCode.n805]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n806]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n807]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n808]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n809]: telco_1.Telco.NineMobile, [network_access_code_1.NetworkAccessCode.n810]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n811]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n812]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n813]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n814]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n815]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n816]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n817]: telco_1.Telco.NineMobile, [network_access_code_1.NetworkAccessCode.n818]: telco_1.Telco.NineMobile, [network_access_code_1.NetworkAccessCode.n900]: telco_1.Telco.Reserved, [network_access_code_1.NetworkAccessCode.n901]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n902]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n903]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n904]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n905]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n906]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n907]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n908]: telco_1.Telco.NineMobile, [network_access_code_1.NetworkAccessCode.n909]: telco_1.Telco.NineMobile, [network_access_code_1.NetworkAccessCode.n911]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n912]: telco_1.Telco.Airtel, [network_access_code_1.NetworkAccessCode.n913]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n914]: telco_1.Telco.MTN, [network_access_code_1.NetworkAccessCode.n915]: telco_1.Telco.Globacom, [network_access_code_1.NetworkAccessCode.n916]: telco_1.Telco.MTN }; TestDataGeneratorBase.initialized = false; TestDataGeneratorBase._networkCodesByTelco = {}; TestDataGeneratorBase._allValidNetworkCodes = []; TestDataGeneratorBase._allValidTelcos = []; /** * Invalid network codes for negative testing */ TestDataGeneratorBase.invalidNetworkCodes = [200, 300, 400, 500, 600, 999]; /** * Special cases within the 702 range */ TestDataGeneratorBase.specialCase702 = { Smile: { min: 0, max: 999999 }, Returned: { min: 1000000, max: 1999999 }, InterconnectClearinghouse: { min: 2000000, max: 2000199 }, Openskys: { min: 3000000, max: 3999999 }, Withdrawn1: { min: 4000000, max: 4999999 }, Visafone: { min: 5000000, max: 6999999 }, Withdrawn2: { min: 7000000, max: 9999999 } };