From 64ac4a0289a49ca51a95ceb03007eb0632325b5c Mon Sep 17 00:00:00 2001 From: Francois Zaninotto Date: Tue, 24 Sep 2013 00:21:00 +0200 Subject: [PATCH] Refactor provider and tests to make it more Faker-like --- src/Faker/Provider/Base.php | 16 ++- src/Faker/Provider/Payment.php | 172 +++++++++++++++++----------- test/Faker/Provider/PaymentTest.php | 45 +++++--- 3 files changed, 149 insertions(+), 84 deletions(-) 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 index f78dee0d..5a017922 100644 --- a/src/Faker/Provider/Payment.php +++ b/src/Faker/Provider/Payment.php @@ -2,90 +2,128 @@ namespace Faker\Provider; -use Faker\Provider\Person; - class Payment extends Base { public static $expirationDateFormat = "m/y"; - protected static $cardsParams = array( - 'visa' => array( - 'mask' => array( - "4539#########", - "4539############", - "4556#########", - "4556############", - "4916#########", - "4916############", - "4532#########", - "4532############", - "4929#########", - "4929############", - "40240071#####", - "40240071########", - "4485#########", - "4485############", - "4716#########", - "4716############", - "4############", - "4###############" - ), - 'name' => 'Visa' + protected static $cardVendors = array( + 'Visa', 'Visa', 'Visa', 'Visa', 'Visa', + 'MasterCard', 'MasterCard', 'MasterCard', 'MasterCard', 'MasterCard', + 'American Express', 'Discover Card' + ); + + // see http://en.wikipedia.org/wiki/Bank_card_number for a reference of existing prefixes + protected static $cardParams = array( + 'Visa' => array( + "4539#########", + "4539############", + "4556#########", + "4556############", + "4916#########", + "4916############", + "4532#########", + "4532############", + "4929#########", + "4929############", + "40240071#####", + "40240071########", + "4485#########", + "4485############", + "4716#########", + "4716############", + "4############", + "4###############" ), - 'mastercard' => array( - 'mask' => array( - "51##############", - "52##############", - "53##############", - "54##############", - "55##############" - ), - 'name' => 'MasterCard' + 'MasterCard' => array( + "51##############", + "52##############", + "53##############", + "54##############", + "55##############" ), - 'amex' => array( - 'mask' => array( - "34#############", - "37#############"), - 'name' => 'American Express' + 'American Express' => array( + "34#############", + "37#############" ), - 'discover' => array( - 'mask' => array("6011############"), - 'name' => 'Discover' + 'Discover Card' => array( + "6011############" ), ); - public static function randomCard($valid = true) + /** + * @return string Returns a credit card vendor name + * + * @example 'MasterCard' + */ + public static function creditCardType() { - $params = static::randomElement(static::$cardsParams); - $CCNumber = static::randomCardNumber($params['mask']); - - return array( - 'type' => $params['name'], - 'number' => $CCNumber, - 'name' => strtoupper(Person::firstName() . " " . Person::lastName()), - 'expirationDate' => static::expirationDate($valid) - ); - } - - public static function randomCardNumber($mask = null) - { - if (is_null($mask)) { - $cp = static::randomElement(static::$cardsParams); - $mask = $cp['mask']; - } - - return static::numerify($mask); + 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 static function expirationDate($valid = true) + public function creditCardExpirationDateString($valid = true, $expirationDateFormat = null) { - $dt = new \DateTime(); - $sign = ($valid) ? '+' : '-'; - $dt->modify(sprintf($sign . "%s %s", rand(1,36), 'month')); + return $this->creditCardExpirationDate($valid)->format(is_null($expirationDateFormat) ? static::$expirationDateFormat : $expirationDateFormat); + } - return $dt->format(static::$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 index 66e08c94..f075feef 100644 --- a/test/Faker/Provider/PaymentTest.php +++ b/test/Faker/Provider/PaymentTest.php @@ -2,31 +2,44 @@ namespace Faker\Test\Provider; -use Faker\Provider\Payment; - class PaymentTest extends \PHPUnit_Framework_TestCase { - - public function testExpirationDate() + public function setUp() { - $dt = new \DateTime('now'); + $faker = new \Faker\Generator(); + $faker->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; + } - $expDate = Payment::expirationDate(true); - $dt2 = \DateTime::createFromFormat(Payment::$expirationDateFormat, $expDate); - $this->assertTrue($dt2 >= $dt); + public function testCreditCardTypeReturnsValidVendorName() + { + $this->assertTrue(in_array($this->faker->creditCardType, array('Visa', 'MasterCard', 'American Express', 'Discover Card'))); + } - $expDate = Payment::expirationDate(false); - $dt2 = \DateTime::createFromFormat(Payment::$expirationDateFormat, $expDate); - $this->assertTrue($dt2 < $dt); + 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() { - $card = Payment::randomCard(); - $this->assertEquals(count($card), 4); - $this->assertEquals(array('type', 'number', 'name', 'expirationDate'), array_keys($card)); - + $cardDetails = $this->faker->creditCardDetails; + $this->assertEquals(count($cardDetails), 4); + $this->assertEquals(array('type', 'number', 'name', 'expirationDate'), array_keys($cardDetails)); } - }