[BUGFIX] Don't save form protection error messages in session
[Packages/TYPO3.CMS.git] / tests / t3lib / formprotection / class.t3lib_formprotection_BackendFormProtectionTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010-2011 Oliver Klee (typo3-coding@oliverklee.de)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * Testcase for the t3lib_formprotection_BackendFormProtection class.
27 *
28 * @package TYPO3
29 * @subpackage t3lib
30 *
31 * @author Oliver Klee <typo3-coding@oliverklee.de>
32 */
33 class t3lib_formprotection_BackendFormProtectionTest extends tx_phpunit_testcase {
34 /**
35 * Enable backup of global and system variables
36 *
37 * @var boolean
38 */
39 protected $backupGlobals = TRUE;
40
41 /**
42 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
43 * because resource types cannot be handled during serializing
44 *
45 * @var array
46 */
47 protected $backupGlobalsBlacklist = array('TYPO3_DB');
48
49
50 /**
51 * @var t3lib_formprotection_BackendFormProtection
52 */
53 private $fixture;
54
55 public function setUp() {
56 $GLOBALS['BE_USER'] = $this->getMock(
57 't3lib_beUserAuth',
58 array('getSessionData', 'setAndSaveSessionData')
59 );
60 $GLOBALS['BE_USER']->user['uid'] = 1;
61
62 $className = $this->createAccessibleProxyClass();
63 $this->fixture = $this->getMock($className, array('acquireLock', 'releaseLock'));
64 }
65
66 public function tearDown() {
67 $this->fixture->__destruct();
68 unset($this->fixture);
69 t3lib_FlashMessageQueue::getAllMessagesAndFlush();
70 }
71
72
73 //////////////////////
74 // Utility functions
75 //////////////////////
76
77 /**
78 * Creates a subclass t3lib_formprotection_BackendFormProtection with retrieveTokens made
79 * public.
80 *
81 * @return string the name of the created class, will not be empty
82 */
83 private function createAccessibleProxyClass() {
84 $className = 't3lib_formprotection_BackendFormProtectionAccessibleProxy';
85 if (!class_exists($className)) {
86 eval(
87 'class ' . $className . ' extends t3lib_formprotection_BackendFormProtection {' .
88 ' public function createValidationErrorMessage() {' .
89 ' parent::createValidationErrorMessage();' .
90 ' }' .
91 ' public function retrieveSessionToken() {' .
92 ' return parent::retrieveSessionToken();' .
93 ' }' .
94 ' public function setSessionToken($sessionToken) {' .
95 ' $this->sessionToken = $sessionToken;' .
96 ' }' .
97 '}'
98 );
99 }
100
101 return $className;
102 }
103
104 /**
105 * Mock session methods in t3lib_beUserAuth
106 *
107 * @return t3lib_beUserAuth Instance of BE_USER object with mocked session storage methods
108 */
109 private function createBackendUserSessionStorageStub() {
110 $className = 't3lib_beUserAuthMocked';
111 if (!class_exists($className)) {
112 eval(
113 'class ' . $className . ' extends t3lib_beUserAuth {' .
114 ' protected $session=array();' .
115 ' public function getSessionData($key) {' .
116 ' return $this->session[$key];' .
117 ' }' .
118 ' public function setAndSaveSessionData($key,$data) {' .
119 ' $this->session[$key] = $data;' .
120 ' }' .
121 '}'
122 );
123 }
124
125 return $this->getMock($className, array('foo'));// $className;
126 }
127
128 ////////////////////////////////////
129 // Tests for the utility functions
130 ////////////////////////////////////
131
132 /**
133 * @test
134 */
135 public function createAccessibleProxyCreatesBackendFormProtectionSubclass() {
136 $className = $this->createAccessibleProxyClass();
137
138 $this->assertTrue(
139 (new $className()) instanceof t3lib_formprotection_BackendFormProtection
140 );
141 }
142
143 /**
144 * @test
145 */
146 public function createBackendUserSessionStorageStubWorkProperly() {
147 $GLOBALS['BE_USER'] = $this->createBackendUserSessionStorageStub();
148
149 $allTokens = array(
150 '12345678' => array(
151 'formName' => 'foo',
152 'action' => 'edit',
153 'formInstanceName' => '42'
154 ),
155 );
156
157 $GLOBALS['BE_USER']->setAndSaveSessionData('tokens', $allTokens);
158
159 $this->assertEquals($GLOBALS['BE_USER']->getSessionData('tokens'), $allTokens);
160 }
161
162
163 //////////////////////////////////////////////////////////
164 // Tests concerning the reading and saving of the tokens
165 //////////////////////////////////////////////////////////
166
167 /**
168 * @test
169 */
170 public function retrieveTokenReadsTokenFromSessionData() {
171 $GLOBALS['BE_USER']->expects($this->once())->method('getSessionData')
172 ->with('formSessionToken')->will($this->returnValue(array()));
173
174 $this->fixture->retrieveSessionToken();
175 }
176
177 /**
178 * @test
179 */
180 public function tokenFromSessionDataIsAvailableForValidateToken() {
181 $sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
182 $formName = 'foo';
183 $action = 'edit';
184 $formInstanceName = '42';
185
186 $tokenId = t3lib_div::hmac($formName . $action . $formInstanceName . $sessionToken);
187
188 $GLOBALS['BE_USER']->expects($this->atLeastOnce())->method('getSessionData')
189 ->with('formSessionToken')
190 ->will($this->returnValue($sessionToken));
191
192 $this->fixture->retrieveSessionToken();
193
194 $this->assertTrue(
195 $this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName)
196 );
197 }
198
199 /**
200 * @expectedException UnexpectedValueException
201 * @test
202 */
203 public function restoreSessionTokenFromRegistryThrowsExceptionIfSessionTokenIsEmpty() {
204 $this->fixture->injectRegistry(
205 $this->getMock('t3lib_Registry')
206 );
207 $this->fixture->setSessionTokenFromRegistry();
208 }
209
210 /**
211 * @test
212 */
213 public function persistSessionTokenWritesTokenToSession() {
214 $sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
215 $this->fixture->setSessionToken($sessionToken);
216
217 $GLOBALS['BE_USER']->expects($this->once())
218 ->method('setAndSaveSessionData')->with('formSessionToken', $sessionToken);
219
220 $this->fixture->persistSessionToken();
221 }
222
223
224 //////////////////////////////////////////////////
225 // Tests concerning createValidationErrorMessage
226 //////////////////////////////////////////////////
227
228 /**
229 * @test
230 */
231 public function createValidationErrorMessageAddsErrorFlashMessage() {
232 $GLOBALS['BE_USER'] = $this->createBackendUserSessionStorageStub();
233 $this->fixture->createValidationErrorMessage();
234
235 $messages = t3lib_FlashMessageQueue::getAllMessagesAndFlush();
236
237 $this->assertNotEmpty($messages);
238 $this->assertContains(
239 $GLOBALS['LANG']->sL(
240 'LLL:EXT:lang/locallang_core.xml:error.formProtection.tokenInvalid'
241 ),
242 $messages[0]->render()
243 );
244 }
245
246 /**
247 * @test
248 */
249 public function createValidationErrorMessageAddsErrorFlashMessageButNotInSessionInAjaxRequest() {
250 $GLOBALS['BE_USER'] = $this->createBackendUserSessionStorageStub();
251 $GLOBALS['TYPO3_AJAX'] = TRUE;
252 $this->fixture->createValidationErrorMessage();
253
254 $messages = t3lib_FlashMessageQueue::$messages;
255
256 $this->assertNotEmpty($messages);
257 $this->assertContains(
258 $GLOBALS['LANG']->sL(
259 'LLL:EXT:lang/locallang_core.xml:error.formProtection.tokenInvalid'
260 ),
261 $messages[0]->render()
262 );
263 }
264 }
265 ?>