Testing

Introduction

LdapRecord comes with a utility that allow you to test bind attempts against a fake server and return custom error codes & responses.

This allows you to test how your application responds to authentication failures and error messages.

Test Case Setup

To begin, initialize the fake directory using the DirectoryFake::setup method. This method accepts the name of your LDAP connection that you initialize in your application.

If you do not provide a name, your default LDAP connection name will be used.

Upon calling the setup method, your LDAP connection will be swapped out of the connection Container and replaced with a ConnectionFake.

Let's walk through an example of testing an application that uses LDAP authentication.

Here's our example controller:

class AuthController
{
    public function __construct()
    {
        Container::addConnection([
            'hosts' => ['10.0.0.1']
        ]);
    }

    public function login()
    {
        $connection = Container::getDefaultConnection();

        $username = $_POST['username'];
        $password = $_POST['password'];

        if ($connection->auth()->attempt($username, $password)) {
            return "Your password is valid!";   
        }

        return "Username or password is incorrect.";
    }
}

Now let's test it:

use LdapRecord\Testing\DirectoryFake;

class LoginTest extends TestCase
{
    public function test_login()
    {
        $user = 'cn=User,dc=local,dc=com';

        DirectoryFake::setup()->actingAs($user);

        // Execute HTTP post request somehow in your testing framework...

        $this->post('/login', [
            'username' => $user,
            'password' => 'secret',
        ])->assertSee("Your password is valid!");

        $this->post('/login', [
            'username' => 'invalid',
            'password' => 'secret',
        ])->assertSee("Username or password is incorrect.");
    }
}

This is a small example of how you can test bind attempts to your LDAP server.

Responses and Error Codes

When testing connectivity to your LDAP server, you may wish to test error codes and messages that may be returned when a bind attempt fails. To do this, you can use the ConnectionFake to retrieve a fake LDAP connection to return error codes when a bind attempt fails.

Let's walk through an example of an authentication controller that will retrieve the last LDAP error and determine the cause of the bind failure.

Let's walk through an example of testing an application that uses LDAP authentication.

Here's our example controller:

class AuthController
{
    public function __construct()
    {
        Container::addConnection([
            'hosts' => ['10.0.0.1']
        ]);
    }

    public function login()
    {
        $connection = Container::getDefaultConnection();

        $username = $_POST['username'];
        $password = $_POST['password'];

        if ($connection->auth()->attempt($username, $password)) {
            return "Your password is valid!";   
        }

        $error = $connection->getLdapConnection()->getDiagnosticMessage();

        if (strpos($error, '532') !== false) {
            return "Your password has expired.";
        } elseif (strpos($error, '533') !== false) {
            return "Your account is disabled.";
        } elseif (strpos($error, '701') !== false) {
             return "Your account has expired.";
        } elseif (strpos($error, '775') !== false) {
             return "Your account is locked.";
        }

        return "Username or password is incorrect.";
    }
}

You can see above that we are pulling the diagnostic message of the last failed bind attempt.

This diagnostic message contains an error code that you can use to tell the user why they failed logging in.

Here is how we would test the above controller:

use LdapRecord\Testing\DirectoryFake;

class LoginTest extends TestCase
{
    public function test_login()
    {
        $user = 'cn=User,dc=local,dc=com';

        $fake = DirectoryFake::setup()->actingAs($user);

        $fake->getLdapConnection()->shouldReturnDiagnosticMessage('Failed: 775');

        // Execute HTTP post request somehow in your testing framework...

        $this->post('/login', [
            'username' => $user,
            'password' => 'secret',
        ])->assertSee("Your account is locked.");
    }
}
← Previous Topic

Logging

Next Topic →

Versioning