Authentication - updating our tests
We've got a new test for our administrator controller, but unfortunately a quick test run shows a problem:
$ ./libraries/lithium/console/li3 test app/tests
----
Test
----
........F
FAIL
8 / 9 passes
1 fail and 0 exceptions
Failed assertion assertEqual.
Class : app\tests\cases\controllers\EmployeesControllerTest
Method : testAdd()
Line : 61
________
expected: 3
result: 2
________
app/tests/cases/controllers/EmployeesControllerTest.php
will need to be updated so that it tests firstly that non-authenticated users cannot add Employees, and secondly that authenticated Administrators
can add Employees.
Here is my updated test:
<?php
namespace app\tests\cases\controllers;
use app\controllers\EmployeesController;
use lithium\action\Request;
use app\models\Employees;
use li3_fixtures\test\Fixtures;
use lithium\net\http\Router;
use app\controllers\AdministratorsController;
class EmployeesControllerTest extends \lithium\test\Unit {
public function setUp() {
Fixtures::config(array(
'db' => array(
'adapter' => 'Connection',
'connection' => 'default',
'fixtures' => array(
'administrators' =>
'app\tests\fixture\AdministratorsFixture',
'employees' => 'app\tests\fixture\EmployeesFixture',
)
)
));
Fixtures::save('db');
Router::connect('/{:controller}/{:action}/{:args}');
}
public function tearDown() {
Fixtures::clear('db');
\lithium\storage\Session::clear();
}
// helper methods
protected function logIn() {
$adminUser = \app\models\Administrators::create();
$adminUser->username = 'foobar';
$adminUser->password = 'barbar';
$adminUser->save();
$loginRequest = new Request();
$loginRequest->data = array(
'username' => 'foobar',
'password' => 'barbar'
);
$adminController = new AdministratorsController(
array('request' => $loginRequest)
);
$response = $adminController->login();
$this->assertEqual(302, $response->status['code']);
return $response;
}
// actual tests
public function testIndexListsEmployeesInTheDatabase() {
$request = new Request();
$request->data = array();
$controller = new EmployeesController(array('request' => $request));
$result = $controller->index();
$this->assertEqual("Foobar", $result['employees'][1]->name);
$this->assertEqual("Bazbip", $result['employees'][2]->name);
$this->assertNull($result['employees'][3]);
}
public function testViewShowsAnIndividualEmployeeMember() {
$request = new Request();
$request->data = array();
$controller = new EmployeesController(array('request' => $request));
$result = $controller->view(1);
$this->assertEqual("Foobar", $result['employee']->name);
}
public function testAddCannotBeUsedByNonAuthenticatedUsers() {
$this->assertEqual(2, count(Employees::all()));
$request = new Request();
$request->data = array(
'name' => 'Brand new user',
'department' => 'Scamping and nonsense'
);
$controller = new EmployeesController(array('request' => $request));
$response = $controller->add();
$this->assertEqual(302, $response->status['code']);
$this->assertEqual(2, count(Employees::all()));
}
public function testAddCanBeUsedByAdministrators() {
$this->logIn();
// create a new user
$this->assertEqual(2, count(Employees::all()));
$request = new Request();
$request->data = array(
'name' => 'Brand new user',
'department' => 'Scamping and nonsense'
);
$controller = new EmployeesController(array('request' => $request));
/* @var $response \lithium\action\Response */
$response2 = $controller->add();
$this->assertEqual(302, $response2->status['code']);
$this->assertEqual(3, count(Employees::all()));
$this->assertContains(
'employees/view/3',
$response2->headers['Location']
);
}
public function testDepartmentIsMandatory() {
$this->logIn();
$this->assertEqual(2, count(Employees::all()));
$request = new Request();
$request->data = array('name' => 'Departmentless user');
$controller = new EmployeesController(array('request' => $request));
$response = $controller->add();
$this->assertEqual(
'Please let us know what department this person works in.',
$response['errors']['department'][0]
);
$this->assertEqual(2, count(Employees::all()));
}
// public function testEdit() {} // exercise for the reader!
// public function testDelete() {} // exercise for the reader!
}
?>
Gosh, there's a lot of code in there! It's not introducing anything new though so I suggest reading through the tests and making sure you follow what's going on. Once again, we're ending the session on every test - otherwise testDepartmentIsMandatory
will work because the preceeding test leaves the user logged in, which is a very brittle way to test a system. Notice also that we pull in the Administrators fixture so that table is available to us.
Right, this should all work now! You should be able to do a complete test run which tests your entire system!
It's a good idea to check that your tests work on both the command line runner and the web runner which lives at /test.
I'm sure at this point you're positively gasping for something DIFFERENT to do! No problem - on to the next thing - error handling!