Skip to content

Commit

Permalink
Improved Handling Of Non Started Sessions
Browse files Browse the repository at this point in the history
Adds logging in the event of the session not being started
Starts the session manually and then reads the SessionUserIdKey

Closes Issue #16
Closes Issue #15

Signed-off-by: Justin Yost <[email protected]>
  • Loading branch information
justinyost committed Jun 23, 2016
1 parent 3d21ed9 commit 374af64
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 13 deletions.
28 changes: 17 additions & 11 deletions src/Model/Behavior/CreatorModifierBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Cake\Network\Request;
use Cake\ORM\Behavior;
use Cake\ORM\Entity;
use \RuntimeException;
use \UnexpectedValueException;

/**
Expand Down Expand Up @@ -159,16 +160,6 @@ protected function updateField(Entity $entity, $field) {
$entity->set($field, $this->getUserId());
}

/**
* Factory method for the Request object.
*
* @return \Cake\Network\Request New instance of the Request object.
* @codeCoverageIgnore Don't test PHP's ability to use new.
*/
protected function newRequest() {
return new Request();
}

/**
* Return the User.id grabbed from the Session information.
*
Expand All @@ -181,9 +172,24 @@ protected function sessionUserId() {
if ($request->session()->started()) {
$userId = $request->session()->read($this->_config['sessionUserIdKey']);
} else {
$this->log('The Session is not started. This typically means a User is not logged in. In this case there is no Session value for the currently active User and therefore we will set the `creator_id` and `modifier_id` to a null value.', 'debug');
$this->log('The Session is not started. This typically means a User is not logged in. In this case there is no Session value for the currently active User and therefore we will set the `creator_id` and `modifier_id` to a null value. As a fallback, we are manually starting the session and reading the `$this->_config[sessionUserIdKey]` value, which is probably not correct.', 'debug');
try {
$request->session()->start();
$userId = $request->session()->read($this->_config['sessionUserIdKey']);
} catch (RuntimeException $e) {
}
}

return $userId;
}

/**
* Factory method for the Request object.
*
* @return \Cake\Network\Request New instance of the Request object.
* @codeCoverageIgnore Don't test PHP's ability to use new.
*/
protected function newRequest() {
return new Request();
}
}
153 changes: 151 additions & 2 deletions tests/TestCase/Model/Behavior/CreatorModifierBehaviorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
use CreatorModifier\Model\Behavior\CreatorModifierBehavior;
use \RuntimeException;

/**
* \CreatorModifier\Test\TestCase\Model\Behavior\TestCreatorModifierBehavior
Expand All @@ -30,6 +31,8 @@ public function sessionUserId() {
* \CreatorModifier\Test\TestCase\Model\Behavior\CreatorModifierBehaviorTest
*
* Tests for the CreatorModifierBehavior class.
*
* @coversDefaultClass \CreatorModifier\Model\Behavior\CreatorModifierBehavior
*/
class CreatorModifierBehaviorTest extends TestCase {
/**
Expand Down Expand Up @@ -235,7 +238,7 @@ public function testGetUserId() {
/**
* Test that getUserId persists and returns the same value for multiple calls.
*
* @depends testGetTimestamp
* @depends testGetUserId
* @return void
*/
public function testGetUserIdPersists($behavior) {
Expand Down Expand Up @@ -423,7 +426,7 @@ public function testUpdateFieldIsClean() {
->with($field, $this->mockedUserUUID)
->will($this->returnValue(true));

$table = $this->getMock('Cake\ORM\Table');
$table = $this->getMock('\Cake\ORM\Table');
$behavior = $this->getMock(
'\CreatorModifier\Test\TestCase\Model\Behavior\TestCreatorModifierBehavior',
['getUserId'],
Expand All @@ -439,4 +442,150 @@ public function testUpdateFieldIsClean() {
'When attempting to update a field marked clean, ::updateField returns null and sets the return from ::getUserId to the field for the Entity.'
);
}

/**
* Test ::sessionUserId when the session exists, is started and returns a value.
*
* @return void
*/
public function testSessionUserIdSessionExists() {
$request = $this->getMock(
'\Cake\Network\Request',
['session', 'started', 'read']
);
$request->expects($this->any())
->method('session')
->with()
->will($this->returnSelf());
$request->expects($this->once())
->method('started')
->with()
->will($this->returnValue(true));
$request->expects($this->once())
->method('read')
->with('Auth.User.id')
->will($this->returnValue($this->mockedUserUUID));

$table = $this->getMock('\Cake\ORM\Table');

$behavior = $this->getMock(
'\CreatorModifier\Test\TestCase\Model\Behavior\TestCreatorModifierBehavior',
['newRequest'],
[$table]
);
$behavior->expects($this->once())
->method('newRequest')
->with()
->will($this->returnValue($request));

$output = $behavior->sessionUserId();
$this->assertEquals(
$this->mockedUserUUID,
$output,
'On the session being started and returns a mocked value, that mocked value should be returned.'
);
}

/**
* Test ::sessionUserId when the session is not started.
*
* @return void
*/
public function testSessionUserIdSessionNotStarted() {
$request = $this->getMock(
'\Cake\Network\Request',
['session', 'started', 'read', 'start']
);
$request->expects($this->any())
->method('session')
->with()
->will($this->returnSelf());
$request->expects($this->once())
->method('started')
->with()
->will($this->returnValue(false));
$request->expects($this->once())
->method('start')
->with()
->will($this->returnValue(true));
$request->expects($this->once())
->method('read')
->with('Auth.User.id')
->will($this->returnValue($this->mockedUserUUID));

$table = $this->getMock('\Cake\ORM\Table');

$behavior = $this->getMock(
'\CreatorModifier\Test\TestCase\Model\Behavior\TestCreatorModifierBehavior',
['newRequest', 'log'],
[$table]
);
$behavior->expects($this->once())
->method('newRequest')
->with()
->will($this->returnValue($request));
$behavior->expects($this->once())
->method('log')
->with($this->anything(), 'debug')
->will($this->returnValue(true));

$output = $behavior->sessionUserId();
$this->assertEquals(
$this->mockedUserUUID,
$output,
'On the session not being already started and then manually started and returns a mocked value, that mocked value should be returned.'
);
}

/**
* Test ::sessionUserId when the session is not started.
*
* @return void
*/
public function testSessionUserIdSessionNotStartedStartingThrowsException() {
$exception = new RuntimeException();

$request = $this->getMock(
'\Cake\Network\Request',
['session', 'started', 'read', 'start']
);
$request->expects($this->any())
->method('session')
->with()
->will($this->returnSelf());
$request->expects($this->once())
->method('started')
->with()
->will($this->returnValue(false));
$request->expects($this->once())
->method('start')
->with()
->will($this->throwException($exception));
$request->expects($this->never())
->method('read')
->with('Auth.User.id')
->will($this->returnValue($this->mockedUserUUID));

$table = $this->getMock('\Cake\ORM\Table');

$behavior = $this->getMock(
'\CreatorModifier\Test\TestCase\Model\Behavior\TestCreatorModifierBehavior',
['newRequest', 'log'],
[$table]
);
$behavior->expects($this->once())
->method('newRequest')
->with()
->will($this->returnValue($request));
$behavior->expects($this->once())
->method('log')
->with($this->anything(), 'debug')
->will($this->returnValue(true));

$output = $behavior->sessionUserId();
$this->assertNull(
$output,
'On the session not being started, a `null` value should be returned.'
);
}
}

0 comments on commit 374af64

Please sign in to comment.