Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * ErrorHandlerTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Error
15
 * @since         CakePHP(tm) v 1.2.0.5432
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('ErrorHandler', 'Error');
20
App::uses('Controller', 'Controller');
21
App::uses('Router', 'Routing');
22
App::uses('Debugger', 'Utility');
23
 
24
/**
25
 * A faulty ExceptionRenderer to test nesting.
26
 */
27
class FaultyExceptionRenderer extends ExceptionRenderer {
28
 
29
/**
30
 * Dummy rendering implementation.
31
 *
32
 * @return void
33
 * @throws Exception
34
 */
35
	public function render() {
36
		throw new Exception('Error from renderer.');
37
	}
38
 
39
}
40
 
41
/**
42
 * ErrorHandlerTest class
43
 *
44
 * @package       Cake.Test.Case.Error
45
 */
46
class ErrorHandlerTest extends CakeTestCase {
47
 
48
	protected $_restoreError = false;
49
 
50
/**
51
 * setup create a request object to get out of router later.
52
 *
53
 * @return void
54
 */
55
	public function setUp() {
56
		parent::setUp();
57
		App::build(array(
58
			'View' => array(
59
				CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
60
			)
61
		), App::RESET);
62
		Router::reload();
63
 
64
		$request = new CakeRequest(null, false);
65
		$request->base = '';
66
		Router::setRequestInfo($request);
67
		Configure::write('debug', 2);
68
 
69
		CakeLog::disable('stdout');
70
		CakeLog::disable('stderr');
71
	}
72
 
73
/**
74
 * tearDown
75
 *
76
 * @return void
77
 */
78
	public function tearDown() {
79
		parent::tearDown();
80
		if ($this->_restoreError) {
81
			restore_error_handler();
82
		}
83
		CakeLog::enable('stdout');
84
		CakeLog::enable('stderr');
85
	}
86
 
87
/**
88
 * test error handling when debug is on, an error should be printed from Debugger.
89
 *
90
 * @return void
91
 */
92
	public function testHandleErrorDebugOn() {
93
		set_error_handler('ErrorHandler::handleError');
94
		$this->_restoreError = true;
95
 
96
		Debugger::getInstance()->output('html');
97
 
98
		ob_start();
99
		$wrong .= '';
100
		$result = ob_get_clean();
101
 
102
		$this->assertRegExp('/<pre class="cake-error">/', $result);
103
		$this->assertRegExp('/<b>Notice<\/b>/', $result);
104
		$this->assertRegExp('/variable:\s+wrong/', $result);
105
	}
106
 
107
/**
108
 * provides errors for mapping tests.
109
 *
110
 * @return void
111
 */
112
	public static function errorProvider() {
113
		return array(
114
			array(E_USER_NOTICE, 'Notice'),
115
			array(E_USER_WARNING, 'Warning'),
116
		);
117
	}
118
 
119
/**
120
 * test error mappings
121
 *
122
 * @dataProvider errorProvider
123
 * @return void
124
 */
125
	public function testErrorMapping($error, $expected) {
126
		set_error_handler('ErrorHandler::handleError');
127
		$this->_restoreError = true;
128
 
129
		Debugger::getInstance()->output('html');
130
 
131
		ob_start();
132
		trigger_error('Test error', $error);
133
 
134
		$result = ob_get_clean();
135
		$this->assertRegExp('/<b>' . $expected . '<\/b>/', $result);
136
	}
137
 
138
/**
139
 * test error prepended by @
140
 *
141
 * @return void
142
 */
143
	public function testErrorSuppressed() {
144
		set_error_handler('ErrorHandler::handleError');
145
		$this->_restoreError = true;
146
 
147
		ob_start();
148
		//@codingStandardsIgnoreStart
149
		@include 'invalid.file';
150
		//@codingStandardsIgnoreEnd
151
		$result = ob_get_clean();
152
		$this->assertTrue(empty($result));
153
	}
154
 
155
/**
156
 * Test that errors go into CakeLog when debug = 0.
157
 *
158
 * @return void
159
 */
160
	public function testHandleErrorDebugOff() {
161
		Configure::write('debug', 0);
162
		Configure::write('Error.trace', false);
163
		if (file_exists(LOGS . 'debug.log')) {
164
			unlink(LOGS . 'debug.log');
165
		}
166
 
167
		set_error_handler('ErrorHandler::handleError');
168
		$this->_restoreError = true;
169
 
170
		$out .= '';
171
 
172
		$result = file(LOGS . 'debug.log');
173
		$this->assertEquals(1, count($result));
174
		$this->assertRegExp(
175
			'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
176
			$result[0]
177
		);
178
		if (file_exists(LOGS . 'debug.log')) {
179
			unlink(LOGS . 'debug.log');
180
		}
181
	}
182
 
183
/**
184
 * Test that errors going into CakeLog include traces.
185
 *
186
 * @return void
187
 */
188
	public function testHandleErrorLoggingTrace() {
189
		Configure::write('debug', 0);
190
		Configure::write('Error.trace', true);
191
		if (file_exists(LOGS . 'debug.log')) {
192
			unlink(LOGS . 'debug.log');
193
		}
194
 
195
		set_error_handler('ErrorHandler::handleError');
196
		$this->_restoreError = true;
197
 
198
		$out .= '';
199
 
200
		$result = file(LOGS . 'debug.log');
201
		$this->assertRegExp(
202
			'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
203
			$result[0]
204
		);
205
		$this->assertRegExp('/^Trace:/', $result[1]);
206
		$this->assertRegExp('/^ErrorHandlerTest\:\:testHandleErrorLoggingTrace\(\)/', $result[2]);
207
		if (file_exists(LOGS . 'debug.log')) {
208
			unlink(LOGS . 'debug.log');
209
		}
210
	}
211
 
212
/**
213
 * test handleException generating a page.
214
 *
215
 * @return void
216
 */
217
	public function testHandleException() {
218
		$error = new NotFoundException('Kaboom!');
219
		ob_start();
220
		ErrorHandler::handleException($error);
221
		$result = ob_get_clean();
222
		$this->assertRegExp('/Kaboom!/', $result, 'message missing.');
223
	}
224
 
225
/**
226
 * test handleException generating log.
227
 *
228
 * @return void
229
 */
230
	public function testHandleExceptionLog() {
231
		if (file_exists(LOGS . 'error.log')) {
232
			unlink(LOGS . 'error.log');
233
		}
234
		Configure::write('Exception.log', true);
235
		$error = new NotFoundException('Kaboom!');
236
 
237
		ob_start();
238
		ErrorHandler::handleException($error);
239
		$result = ob_get_clean();
240
		$this->assertRegExp('/Kaboom!/', $result, 'message missing.');
241
 
242
		$log = file(LOGS . 'error.log');
243
		$this->assertContains('[NotFoundException] Kaboom!', $log[0], 'message missing.');
244
		$this->assertContains('ErrorHandlerTest->testHandleExceptionLog', $log[2], 'Stack trace missing.');
245
	}
246
 
247
/**
248
 * test handleException generating log.
249
 *
250
 * @return void
251
 */
252
	public function testHandleExceptionLogSkipping() {
253
		if (file_exists(LOGS . 'error.log')) {
254
			unlink(LOGS . 'error.log');
255
		}
256
		Configure::write('Exception.log', true);
257
		Configure::write('Exception.skipLog', array('NotFoundException'));
258
		$notFound = new NotFoundException('Kaboom!');
259
		$forbidden = new ForbiddenException('Fooled you!');
260
 
261
		ob_start();
262
		ErrorHandler::handleException($notFound);
263
		$result = ob_get_clean();
264
		$this->assertRegExp('/Kaboom!/', $result, 'message missing.');
265
 
266
		ob_start();
267
		ErrorHandler::handleException($forbidden);
268
		$result = ob_get_clean();
269
		$this->assertRegExp('/Fooled you!/', $result, 'message missing.');
270
 
271
		$log = file(LOGS . 'error.log');
272
		$this->assertNotContains('[NotFoundException] Kaboom!', $log[0], 'message should not be logged.');
273
		$this->assertContains('[ForbiddenException] Fooled you!', $log[0], 'message missing.');
274
	}
275
 
276
/**
277
 * tests it is possible to load a plugin exception renderer
278
 *
279
 * @return void
280
 */
281
	public function testLoadPluginHandler() {
282
		App::build(array(
283
			'Plugin' => array(
284
				CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
285
			)
286
		), App::RESET);
287
		CakePlugin::load('TestPlugin');
288
		Configure::write('Exception.renderer', 'TestPlugin.TestPluginExceptionRenderer');
289
		$error = new NotFoundException('Kaboom!');
290
		ob_start();
291
		ErrorHandler::handleException($error);
292
		$result = ob_get_clean();
293
		$this->assertEquals('Rendered by test plugin', $result);
294
		CakePlugin::unload();
295
	}
296
 
297
/**
298
 * test handleFatalError generating a page.
299
 *
300
 * These tests start two buffers as handleFatalError blows the outer one up.
301
 *
302
 * @return void
303
 */
304
	public function testHandleFatalErrorPage() {
305
		$line = __LINE__;
306
 
307
		ob_start();
308
		ob_start();
309
		Configure::write('debug', 1);
310
		ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
311
		$result = ob_get_clean();
312
		$this->assertContains('Something wrong', $result, 'message missing.');
313
		$this->assertContains(__FILE__, $result, 'filename missing.');
314
		$this->assertContains((string)$line, $result, 'line missing.');
315
 
316
		ob_start();
317
		ob_start();
318
		Configure::write('debug', 0);
319
		ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
320
		$result = ob_get_clean();
321
		$this->assertNotContains('Something wrong', $result, 'message must not appear.');
322
		$this->assertNotContains(__FILE__, $result, 'filename must not appear.');
323
		$this->assertContains('An Internal Error Has Occurred', $result);
324
	}
325
 
326
/**
327
 * test handleException generating log.
328
 *
329
 * @return void
330
 */
331
	public function testHandleFatalErrorLog() {
332
		if (file_exists(LOGS . 'error.log')) {
333
			unlink(LOGS . 'error.log');
334
		}
335
 
336
		ob_start();
337
		ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, __LINE__);
338
		ob_clean();
339
 
340
		$log = file(LOGS . 'error.log');
341
		$this->assertContains(__FILE__, $log[0], 'missing filename');
342
		$this->assertContains('[FatalErrorException] Something wrong', $log[1], 'message missing.');
343
	}
344
 
345
/**
346
 * testExceptionRendererNestingDebug method
347
 *
348
 * @return void
349
 */
350
	public function testExceptionRendererNestingDebug() {
351
		Configure::write('debug', 2);
352
		Configure::write('Exception.renderer', 'FaultyExceptionRenderer');
353
 
354
		$result = false;
355
		try {
356
			ob_start();
357
			ob_start();
358
			ErrorHandler::handleFatalError(E_USER_ERROR, 'Initial error', __FILE__, __LINE__);
359
		} catch (Exception $e) {
360
			$result = $e instanceof FatalErrorException;
361
		}
362
 
363
		restore_error_handler();
364
		$this->assertTrue($result);
365
	}
366
 
367
/**
368
 * testExceptionRendererNestingProduction method
369
 *
370
 * @return void
371
 */
372
	public function testExceptionRendererNestingProduction() {
373
		Configure::write('debug', 0);
374
		Configure::write('Exception.renderer', 'FaultyExceptionRenderer');
375
 
376
		$result = false;
377
		try {
378
			ob_start();
379
			ob_start();
380
			ErrorHandler::handleFatalError(E_USER_ERROR, 'Initial error', __FILE__, __LINE__);
381
		} catch (Exception $e) {
382
			$result = $e instanceof InternalErrorException;
383
		}
384
 
385
		restore_error_handler();
386
		$this->assertTrue($result);
387
	}
388
 
389
}