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.

398 lines (397 loc) 22.3 kB
"use strict"; // src/__tests__/synthetic-data/test-data-generator-property-based.ts var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TestDataGeneratorPropertyBased = void 0; const test_data_generator_base_1 = require("./test-data-generator-base"); const test_data_generator_valid_numbers_1 = require("./test-data-generator-valid-numbers"); const test_data_generator_random_numbers_1 = require("./test-data-generator-random-numbers"); const mobile_validation_status_1 = require("../../number-validation/mobile-validation-status"); const telco_1 = require("../../numbering-plan/telco"); const network_access_code_1 = require("../../numbering-plan/network-access-code"); const chance_1 = __importDefault(require("chance")); const test_data_generator_invalid_numbers_1 = require("./test-data-generator-invalid-numbers"); // Initialize Chance with a seed for reproducibility if needed const chance = new chance_1.default(); /** * Generator for property-based testing data */ class TestDataGeneratorPropertyBased extends test_data_generator_base_1.TestDataGeneratorBase { /** * Generate a property-based test for a specific validation aspect * @param aspect The validation aspect to test * @param count Number of test cases to generate */ // eslint-disable-next-line sonarjs/cognitive-complexity static generatePropertyBasedTest(aspect, count = 10) { const testCases = []; switch (aspect) { case 'format': // Generate numbers with different formats (local, international, with plus) for (let i = 0; i < count; i++) { const format = chance.pickone(['local', 'international', 'international-plus']); const networkCode = this.randomNetworkCode(); let number; if (format === 'local') { number = `0${networkCode}${this.randomSubscriberNumber(networkCode)}`; } else if (format === 'international') { number = `234${networkCode}${this.randomSubscriberNumber(networkCode)}`; } else { number = `+234${networkCode}${this.randomSubscriberNumber(networkCode)}`; } testCases.push({ number, description: `Valid number in ${format} format`, expectedValid: true, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', format] }); } break; case 'length': // Generate numbers with different lengths for (let i = 0; i < count; i++) { const networkCode = this.randomNetworkCode(); const correctLength = chance.bool(); let number; if (correctLength) { number = `0${networkCode}${this.randomSubscriberNumber(networkCode)}`; testCases.push({ number, description: 'Valid number with correct length', expectedValid: true, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', 'length'] }); } else { const tooLong = chance.bool(); number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateInvalidLengthNumber(networkCode, tooLong); testCases.push({ number, description: `Invalid number - ${tooLong ? 'too many' : 'too few'} digits`, expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.IncorrectNumberOfDigits, tags: ['invalid', 'length'] }); } } break; case 'chars': // Generate numbers with/without non-numeric characters for (let i = 0; i < count; i++) { const networkCode = this.randomNetworkCode(); const hasNonNumeric = chance.bool(); if (hasNonNumeric) { const number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateNonNumericNumber(networkCode); testCases.push({ number, description: 'Invalid number - contains non-numeric characters', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.ContainsNonNumericChars, tags: ['invalid', 'chars'] }); } else { const number = `0${networkCode}${this.randomSubscriberNumber(networkCode)}`; testCases.push({ number, description: 'Valid number - only contains digits', expectedValid: true, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', 'chars'] }); } } break; case 'network': // Generate numbers with valid/invalid network codes for (let i = 0; i < count; i++) { const validNetwork = chance.bool(); if (validNetwork) { const networkCode = this.randomNetworkCode(); const number = `0${networkCode}${this.randomSubscriberNumber(networkCode)}`; testCases.push({ number, description: 'Valid number - correct network code', expectedValid: true, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', 'network'] }); } else { const number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateInvalidNetworkCodeNumber(); testCases.push({ number, description: 'Invalid number - incorrect network code', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.IncorrectNetworkCode, tags: ['invalid', 'network'] }); } } break; case 'telco': // Generate numbers for different telcos for (const telco of this.allValidTelcos) { const number = test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateValidNumberForTelco(telco); testCases.push({ number, description: `Valid ${telco} number`, expectedValid: true, expectedTelco: telco, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', 'telco', telco.toLowerCase()] }); } // Add special 702 cases testCases.push({ number: test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateValidNumberForTelco(telco_1.Telco.Smile), description: 'Valid Smile number (702 range)', expectedValid: true, expectedTelco: telco_1.Telco.Smile, expectedNetworkCode: network_access_code_1.NetworkAccessCode.n702, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', 'telco', 'smile', '702'] }); testCases.push({ number: test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateValidNumberForTelco(telco_1.Telco.Openskys), description: 'Valid Openskys number (702 range)', expectedValid: true, expectedTelco: telco_1.Telco.Openskys, expectedNetworkCode: network_access_code_1.NetworkAccessCode.n702, expectedStatus: mobile_validation_status_1.MobileValidationStatus.Success, tags: ['valid', 'telco', 'openskys', '702'] }); break; case 'special': // Special case numbers like shared VAS, reserved, withdrawn testCases.push({ number: '07001234567', description: 'Shared VAS network code', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.SharedVASNetworkCode, tags: ['invalid', 'special', 'vas'] }); testCases.push({ number: '07091234567', description: 'Withdrawn network code', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.WithdrawnNetworkCode, tags: ['invalid', 'special', 'withdrawn'] }); testCases.push({ number: '09001234567', description: 'Reserved network code', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.ReservedNetworkCode, tags: ['invalid', 'special', 'reserved'] }); testCases.push({ number: test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateReturned702Number(), description: 'Returned number in 702 range', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.ReturnedNetworkCode, tags: ['invalid', 'special', 'returned', '702'] }); testCases.push({ number: test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateWithdrawn702Number(), description: 'Withdrawn number in 702 range', expectedValid: false, expectedStatus: mobile_validation_status_1.MobileValidationStatus.WithdrawnNetworkCode, tags: ['invalid', 'special', 'withdrawn', '702'] }); break; } return testCases; } /** * Generate random numbers for property-based testing * Each number has a certain probability of being valid or having different types of issues * * @param count Number of test cases to generate * @returns Array of test cases with expected properties */ static generatePropertyBasedTestCases(count = 100) { const testCases = []; for (let i = 0; i < count; i++) { const testType = chance.pickone([ 'valid-local', 'valid-international', 'valid-international-plus', 'valid-with-spaces', 'valid-with-o', 'invalid-format', 'invalid-length', 'invalid-chars', 'invalid-network', 'special-case' ]); let number; let expectedValid; let expectedTelco; let expectedNetworkCode; let expectedStatus; let description; let tags = []; switch (testType) { case 'valid-local': const telco = chance.pickone(this.allValidTelcos); number = test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateValidNumberForTelco(telco); expectedValid = true; expectedTelco = telco; // Handle special case for 702 range if (number.startsWith('0702')) { expectedNetworkCode = network_access_code_1.NetworkAccessCode.n702; } else { const networkCode = parseInt(number.substring(1, 4)); expectedNetworkCode = networkCode; } expectedStatus = mobile_validation_status_1.MobileValidationStatus.Success; description = `Valid ${telco} number in local format`; tags = ['valid', 'local', telco.toLowerCase()]; break; case 'valid-international': const intTelco = chance.pickone(this.allValidTelcos); const intNetworkCode = this.randomNetworkCodeForTelco(intTelco); number = test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateInternationalNumber(intNetworkCode); expectedValid = true; expectedTelco = intTelco; expectedNetworkCode = intNetworkCode; expectedStatus = mobile_validation_status_1.MobileValidationStatus.Success; description = `Valid ${intTelco} number in international format`; tags = ['valid', 'international', intTelco.toLowerCase()]; break; case 'valid-international-plus': const intPlusTelco = chance.pickone(this.allValidTelcos); const intPlusNetworkCode = this.randomNetworkCodeForTelco(intPlusTelco); number = test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateInternationalPlusNumber(intPlusNetworkCode); expectedValid = true; expectedTelco = intPlusTelco; expectedNetworkCode = intPlusNetworkCode; expectedStatus = mobile_validation_status_1.MobileValidationStatus.Success; description = `Valid ${intPlusTelco} number in international format with plus`; tags = ['valid', 'international-plus', intPlusTelco.toLowerCase()]; break; case 'valid-with-spaces': const spacesTelco = chance.pickone(this.allValidTelcos); const spacesNetworkCode = this.randomNetworkCodeForTelco(spacesTelco); number = test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateNumberWithSpaces(spacesNetworkCode); expectedValid = true; expectedTelco = spacesTelco; expectedNetworkCode = spacesNetworkCode; expectedStatus = mobile_validation_status_1.MobileValidationStatus.Success; description = `Valid ${spacesTelco} number with spaces`; tags = ['valid', 'spaces', spacesTelco.toLowerCase()]; break; case 'valid-with-o': const oTelco = chance.pickone(this.allValidTelcos); const oNetworkCode = this.randomNetworkCodeForTelco(oTelco); number = test_data_generator_valid_numbers_1.TestDataGeneratorValidNumbers.generateNumberWithO(oNetworkCode); expectedValid = true; expectedTelco = oTelco; expectedNetworkCode = oNetworkCode; expectedStatus = mobile_validation_status_1.MobileValidationStatus.Success; description = `Valid ${oTelco} number with 'o' instead of '0'`; tags = ['valid', 'o-instead-of-0', oTelco.toLowerCase()]; break; case 'invalid-format': const netCode = this.randomNetworkCode(); number = netCode + this.randomSubscriberNumber(netCode); // Missing leading 0 expectedValid = false; expectedStatus = mobile_validation_status_1.MobileValidationStatus.NotNigerianNumber; description = 'Invalid number - incorrect format'; tags = ['invalid', 'format']; break; case 'invalid-length': const lengthNetworkCode = this.randomNetworkCode(); const tooLong = chance.bool(); number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateInvalidLengthNumber(lengthNetworkCode, tooLong); expectedValid = false; expectedStatus = mobile_validation_status_1.MobileValidationStatus.IncorrectNumberOfDigits; description = `Invalid number - ${tooLong ? 'too many' : 'too few'} digits`; tags = ['invalid', 'length']; break; case 'invalid-chars': const charsNetworkCode = this.randomNetworkCode(); number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateNonNumericNumber(charsNetworkCode); expectedValid = false; expectedStatus = mobile_validation_status_1.MobileValidationStatus.ContainsNonNumericChars; description = 'Invalid number - contains non-numeric characters'; tags = ['invalid', 'chars']; break; case 'invalid-network': number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateInvalidNetworkCodeNumber(); expectedValid = false; expectedStatus = mobile_validation_status_1.MobileValidationStatus.IncorrectNetworkCode; description = 'Invalid number - incorrect network code'; tags = ['invalid', 'network']; break; case 'special-case': const specialCase = chance.pickone([ 'shared-vas', 'withdrawn', 'reserved', 'returned-702', 'withdrawn-702' ]); switch (specialCase) { case 'shared-vas': number = '07001234567'; expectedStatus = mobile_validation_status_1.MobileValidationStatus.SharedVASNetworkCode; description = 'Invalid number - Shared VAS network code'; break; case 'withdrawn': number = '07091234567'; expectedStatus = mobile_validation_status_1.MobileValidationStatus.WithdrawnNetworkCode; description = 'Invalid number - Withdrawn network code'; break; case 'reserved': number = '09001234567'; expectedStatus = mobile_validation_status_1.MobileValidationStatus.ReservedNetworkCode; description = 'Invalid number - Reserved network code'; break; case 'returned-702': number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateReturned702Number(); expectedStatus = mobile_validation_status_1.MobileValidationStatus.WithdrawnNetworkCode; description = 'Invalid number - Returned 702 range'; break; case 'withdrawn-702': number = test_data_generator_invalid_numbers_1.TestDataGeneratorInvalidNumbers.generateWithdrawn702Number(); expectedStatus = mobile_validation_status_1.MobileValidationStatus.WithdrawnNetworkCode; description = 'Invalid number - Withdrawn 702 range'; break; default: number = '09001234567'; expectedStatus = mobile_validation_status_1.MobileValidationStatus.ReservedNetworkCode; description = 'Invalid number - fallback to Reserved network code'; } expectedValid = false; tags = ['invalid', 'special', specialCase]; break; default: // Generate a fully random number as fallback number = test_data_generator_random_numbers_1.TestDataGeneratorRandomNumbers.generateRandomPhoneNumber(); expectedValid = false; description = `Random test case ${i}`; tags = ['random']; } testCases.push({ number, description, expectedValid, expectedTelco, expectedNetworkCode, expectedStatus, tags }); } return testCases; } } exports.TestDataGeneratorPropertyBased = TestDataGeneratorPropertyBased;