Browse Source

4.x - Explicit write & close of the session
- Session::close did not have an implementation for CLI
- SessionEquals and FlashParamEquals integration test constraints cannot use Session instance anymore, since Server now closes the session (read operation would reopen it, which for CLI means that it erases $_SESSION superglobal)

Ján Súkeník 6 years ago
parent
commit
0b19982ec9

+ 6 - 0
src/Http/Session.php

@@ -378,6 +378,12 @@ class Session
             return true;
         }
 
+        if ($this->_isCLI) {
+            $this->_started = false;
+
+            return true;
+        }
+
         if (!session_write_close()) {
             throw new RuntimeException('Could not close the session');
         }

+ 7 - 2
src/TestSuite/Constraint/Session/FlashParamEquals.php

@@ -16,6 +16,7 @@ declare(strict_types=1);
 namespace Cake\TestSuite\Constraint\Session;
 
 use Cake\Http\Session;
+use Cake\Utility\Hash;
 use PHPUnit\Framework\AssertionFailedError;
 use PHPUnit\Framework\Constraint\Constraint;
 
@@ -76,9 +77,13 @@ class FlashParamEquals extends Constraint
      */
     public function matches($other): bool
     {
-        $messages = (array)$this->session->read('Flash.' . $this->key);
+        // Server::run calls Session::close at the end of the request.
+        // Which means, that we cannot use Session object here to access the session data.
+        // Call to Session::read will start new session (and will erase the data).
+
+        $messages = (array)Hash::get($_SESSION, 'Flash.' . $this->key);
         if ($this->at) {
-            $messages = [$this->session->read('Flash.' . $this->key . '.' . $this->at)];
+            $messages = [Hash::get($_SESSION, 'Flash.' . $this->key . '.' . $this->at)];
         }
 
         foreach ($messages as $message) {

+ 5 - 1
src/TestSuite/Constraint/Session/SessionEquals.php

@@ -16,6 +16,7 @@ declare(strict_types=1);
 namespace Cake\TestSuite\Constraint\Session;
 
 use Cake\Http\Session;
+use Cake\Utility\Hash;
 use PHPUnit\Framework\AssertionFailedError;
 use PHPUnit\Framework\Constraint\Constraint;
 
@@ -65,7 +66,10 @@ class SessionEquals extends Constraint
      */
     public function matches($other): bool
     {
-        return $this->session->read($this->path) === $other;
+        // Server::run calls Session::close at the end of the request.
+        // Which means, that we cannot use Session object here to access the session data.
+        // Call to Session::read will start new session (and will erase the data).
+        return Hash::get($_SESSION, $this->path) === $other;
     }
 
     /**

+ 8 - 12
tests/TestCase/Http/SessionTest.php

@@ -18,7 +18,8 @@ namespace Cake\Test\TestCase\Http;
 
 use Cake\Http\Session;
 use Cake\TestSuite\TestCase;
-use RuntimeException;
+use InvalidArgumentException;
+use TestApp\Http\Session\TestAppLibSession;
 use TestApp\Http\Session\TestWebSession;
 
 /**
@@ -261,18 +262,13 @@ class SessionTest extends TestCase
      *
      * @return void
      */
-    public function testCloseFailure()
+    public function testCloseNotStarted()
     {
         $session = new Session();
-        $session->started();
         $this->assertTrue($session->start());
-        try {
-            $session->close();
-        } catch (RuntimeException $e) {
-            // closing the session in CLI should raise an error
-            // and won't close the session.
-            $this->assertTrue($session->started());
-        }
+
+        $session->close();
+        $this->assertFalse($session->started());
     }
 
     /**
@@ -489,7 +485,7 @@ class SessionTest extends TestCase
     public function testEngineWithPreMadeInstance()
     {
         static::setAppNamespace();
-        $engine = new \TestApp\Http\Session\TestAppLibSession();
+        $engine = new TestAppLibSession();
         $session = new Session(['handler' => ['engine' => $engine]]);
         $this->assertSame($engine, $session->engine());
 
@@ -505,7 +501,7 @@ class SessionTest extends TestCase
      */
     public function testBadEngine()
     {
-        $this->expectException(\InvalidArgumentException::class);
+        $this->expectException(InvalidArgumentException::class);
         $this->expectExceptionMessage('The class "Derp" does not exist and cannot be used as a session engine');
         $session = new Session();
         $session->engine('Derp');