diff --git a/readme.md b/readme.md index 40471a9c..d94181a6 100644 --- a/readme.md +++ b/readme.md @@ -195,6 +195,13 @@ Each of the generator properties (like `name`, `address`, and `lorem`) are calle safeColorName // 'fuchsia' colorName // 'Gainsbor' +### `Faker\Provider\Payment` + + creditCardType // 'MasterCard' + creditCardNumber($type = null) // '4485480221084675' + creditCardExpirationDate($valid = true) // DateTime('2014-10-23 13:46:23') + creditCardExpirationDateString($valid = true) // '10/14' + ## Unique and Optional modifiers Faker provides two special providers, `unique()` and `optional()`, to be called before any provider. `optional()` can be useful for seeding non-required fields, like a mobile telephone number ; `unique()` is required to populate fields that cannot accept twice the same value, like primary identifiers. diff --git a/src/Faker/Provider/Base.php b/src/Faker/Provider/Base.php index 654e9a12..acfcba19 100644 --- a/src/Faker/Provider/Base.php +++ b/src/Faker/Provider/Base.php @@ -130,10 +130,24 @@ class Base */ public static function randomElement($array = array('a', 'b', 'c')) { + return $array ? $array[self::randomKey($array)] : null; + } + + /** + * Returns a random key from a passed associative array + * + * @param array $array + * @return mixed + */ + public static function randomKey($array = array()) + { + if (!$array) { + return null; + } $keys = array_keys($array); $key = $keys[mt_rand(0, count($keys) - 1)]; - return $array[$key]; + return $key; } /** diff --git a/src/Faker/Provider/Payment.php b/src/Faker/Provider/Payment.php new file mode 100644 index 00000000..5a017922 --- /dev/null +++ b/src/Faker/Provider/Payment.php @@ -0,0 +1,129 @@ + array( + "4539#########", + "4539############", + "4556#########", + "4556############", + "4916#########", + "4916############", + "4532#########", + "4532############", + "4929#########", + "4929############", + "40240071#####", + "40240071########", + "4485#########", + "4485############", + "4716#########", + "4716############", + "4############", + "4###############" + ), + 'MasterCard' => array( + "51##############", + "52##############", + "53##############", + "54##############", + "55##############" + ), + 'American Express' => array( + "34#############", + "37#############" + ), + 'Discover Card' => array( + "6011############" + ), + ); + + /** + * @return string Returns a credit card vendor name + * + * @example 'MasterCard' + */ + public static function creditCardType() + { + return static::randomElement(static::$cardVendors); + } + + /** + * Returns the String of a credit card number. + * + * @param string $type Supporting any of 'Visa', 'MasterCard', 'Amercian Express', and 'Discover' + * @param boolean $formatted Set to true if the output string should contain one separator every 4 digits + * @param string $separator Separator string for formatting card number. Defaults to dash (-). + * + * @example '4485480221084675' + */ + public static function creditCardNumber($type = null, $formatted = false, $separator = '-') + { + if (is_null($type)) { + $type = static::cardType(); + } + $mask = static::randomElement(static::$cardParams[$type]); + + $number = static::numerify($mask); + + if ($formatted) { + $p1 = substr($number, 0, 4); + $p2 = substr($number, 4, 4); + $p3 = substr($number, 8, 4); + $p4 = substr($number, 12); + $number = $p1 .$separator . $p2 . $separator . $p3 . $separator . $p4; + } + + return $number; + } + + /** + * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date + * @example 04/13 + */ + public function creditCardExpirationDate($valid = true) + { + if ($valid) { + return $this->generator->dateTimeBetween('now', '36 months'); + } + return $this->generator->dateTimeBetween('-36 months', '36 months'); + } + + /** + * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date + * @param string $expirationDateFormat + * @example '04/13' + */ + public function creditCardExpirationDateString($valid = true, $expirationDateFormat = null) + { + return $this->creditCardExpirationDate($valid)->format(is_null($expirationDateFormat) ? static::$expirationDateFormat : $expirationDateFormat); + } + + /** + * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date + * @return array() + */ + public function creditCardDetails($valid = true) + { + $type = static::creditCardType(); + + return array( + 'type' => $type, + 'number' => static::creditCardNumber($type), + 'name' => $this->generator->name(), + 'expirationDate' => $this->creditCardExpirationDateString($valid) + ); + } +} diff --git a/test/Faker/Provider/PaymentTest.php b/test/Faker/Provider/PaymentTest.php new file mode 100644 index 00000000..f075feef --- /dev/null +++ b/test/Faker/Provider/PaymentTest.php @@ -0,0 +1,45 @@ +addProvider(new \Faker\Provider\Base($faker)); + $faker->addProvider(new \Faker\Provider\DateTime($faker)); + $faker->addProvider(new \Faker\Provider\Person($faker)); + $faker->addProvider(new \Faker\Provider\Payment($faker)); + $this->faker = $faker; + } + + public function testCreditCardTypeReturnsValidVendorName() + { + $this->assertTrue(in_array($this->faker->creditCardType, array('Visa', 'MasterCard', 'American Express', 'Discover Card'))); + } + + public function testCreditCardNumberReturnsValidCreditCardNumber() + { + $this->assertRegExp('/^6011\d{12}$/', $this->faker->creditCardNumber('Discover Card')); + } + + public function testCreditCardNumberCanFormatOutput() + { + $this->assertRegExp('/^6011-\d{4}-\d{4}-\d{4}$/', $this->faker->creditCardNumber('Discover Card', true)); + } + + public function testCreditCardExpirationDateReturnsValidDateByDefault() + { + $expirationDate = $this->faker->creditCardExpirationDate; + $this->assertTrue(intval($expirationDate->format('U')) > strtotime('now')); + $this->assertTrue(intval($expirationDate->format('U')) < strtotime('+36 months')); + } + + public function testRandomCard() + { + $cardDetails = $this->faker->creditCardDetails; + $this->assertEquals(count($cardDetails), 4); + $this->assertEquals(array('type', 'number', 'name', 'expirationDate'), array_keys($cardDetails)); + } +}