Skip to content

Instantly share code, notes, and snippets.

@echosa
Created March 12, 2014 22:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save echosa/9518260 to your computer and use it in GitHub Desktop.
Save echosa/9518260 to your computer and use it in GitHub Desktop.
User class for an assignment I was given
<?php
/**
* A few notes on this code.
*
* First, I installed PHPUnit via composer to run the tests. This is the reason for the
* require_once.
*
* Second, I made this all one file (multiple classes) in order to make it easier to
* post to a gist. Normally, of course, I'd have separate paths/files for different
* classes. If you put this all into one file to check/run with phpunit, you'll need to
* name the file something other than User.php, as it normally would be named if it were
* just the User class. I've named the gist UserAssignment.php.
*
* Third, normally I would have pulled the password stuff out into its own class, but
* the instructions were to create a simple class so I didn't. If this were production
* code, I would recommend refactoring into a separate Password class that the static
* method would instantiate and use.
*
* Fourth, even though I didn't refactor into a Password class, I did make a custom
* exception: InvalidFieldException. It felt like the right thing to do.
*/
namespace User;
require_once __DIR__ . '/vendor/autoload.php';
class User
{
const MIN_PASSWORD_LENGTH = 8;
private $_firstName;
private $_lastName;
public static function isValidPassword($password)
{
$isValid = true;
if (empty($password) || strlen($password) < self::MIN_PASSWORD_LENGTH) {
$isValid = false;
} else {
$hasNumeric = false;
$hasLowerCase = false;
$hasUpperCase = false;
$hasPunctuation = false;
foreach (str_split($password) as $char) {
if (ctype_digit($char)) {
$hasNumeric = true;
} elseif (ctype_upper($char)) {
$hasUpperCase = true;
} elseif (ctype_lower($char)) {
$hasLowerCase = true;
} elseif (ctype_punct($char)) {
$hasPunctuation = true;
}
}
if (!$hasNumeric || !$hasUpperCase || !$hasLowerCase || !$hasPunctuation) {
$isValid = false;
}
}
return $isValid;
}
public function getFirstName()
{
return $this->_firstName;
}
public function setFirstName($name)
{
$this->_firstName = $name;
}
public function getLastName()
{
return $this->_lastName;
}
public function setLastName($name)
{
$this->_lastName = $name;
}
public function __get($field)
{
$field = $this->_checkField($field);
return $this->$field;
}
public function __set($field, $value)
{
$field = $this->_checkField($field);
$this->$field = $value;
}
private function _checkField($field)
{
$field = '_' . $field;
if (!property_exists($this, $field)) {
throw new InvalidFieldException($field);
}
return $field;
}
}
class InvalidFieldException extends \Exception
{
public function __construct($field, $code = 0, \Exception $previous = null)
{
$message = $field . ' is not a valid property!';
parent::__construct($message, $code, $previous);
}
}
class UserTest extends \PHPUnit_Framework_TestCase
{
private $_user;
public function setUp()
{
$this->_user = new User();
}
public function testMagicMethodFirstNameShouldNotThrowException()
{
$name = "John";
$this->_user->firstName = $name;
$this->assertEquals($name, $this->_user->firstName);
}
/**
* @expectedException \User\InvalidFieldException
* @expectedExceptionMessage foo is not a valid property!
*/
public function testMagicMethodFooShouldThrowException()
{
$this->_user->foo = 'foo';
}
public function testEmptyPasswordShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword(''));
}
public function testLessThanEightCharactersShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('Ab3456.'));
}
public function testAllNumbersShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('1234567890'));
}
public function testNoNumbersShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('ABCDEFGabc.'));
}
public function testAllCapsShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('ABCDEFGHIJ'));
}
public function testNoCapsShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('1abcdefghij.'));
}
public function testAllLowerShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('abcdefgh'));
}
public function testNoLowerShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('1ABCDEF.'));
}
public function testAllPunctuationShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('.,!@#$%^&*()[]-=_+'));
}
public function testNoPunctuationShouldNotBeValid()
{
$this->assertFalse(User::isValidPassword('1Abcdefg'));
}
public function testProperPasswordShouldBeValid()
{
$this->assertTrue(User::isValidPassword('1Abcdef.'));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment