HandleExceptionsTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace Illuminate\Tests\Foundation\Bootstrap;
  3. use ErrorException;
  4. use Illuminate\Config\Repository as Config;
  5. use Illuminate\Foundation\Application;
  6. use Illuminate\Foundation\Bootstrap\HandleExceptions;
  7. use Illuminate\Log\LogManager;
  8. use Mockery as m;
  9. use Monolog\Handler\NullHandler;
  10. use PHPUnit\Framework\TestCase;
  11. use ReflectionClass;
  12. class HandleExceptionsTest extends TestCase
  13. {
  14. protected function setUp(): void
  15. {
  16. $this->app = Application::setInstance(new Application);
  17. $this->config = new Config();
  18. $this->app->singleton('config', function () {
  19. return $this->config;
  20. });
  21. $this->handleExceptions = new HandleExceptions();
  22. with(new ReflectionClass($this->handleExceptions), function ($reflection) {
  23. $property = tap($reflection->getProperty('app'))->setAccessible(true);
  24. $property->setValue(
  25. $this->handleExceptions,
  26. tap(m::mock($this->app), function ($app) {
  27. $app->shouldReceive('runningUnitTests')->andReturn(false);
  28. $app->shouldReceive('hasBeenBootstrapped')->andReturn(true);
  29. })
  30. );
  31. });
  32. }
  33. protected function tearDown(): void
  34. {
  35. Application::setInstance(null);
  36. }
  37. public function testPhpDeprecations()
  38. {
  39. $logger = m::mock(LogManager::class);
  40. $this->app->instance(LogManager::class, $logger);
  41. $logger->shouldReceive('channel')->with('deprecations')->andReturnSelf();
  42. $logger->shouldReceive('warning')->with(sprintf('%s in %s on line %s',
  43. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  44. '/home/user/laravel/routes/web.php',
  45. 17
  46. ));
  47. $this->handleExceptions->handleError(
  48. E_DEPRECATED,
  49. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  50. '/home/user/laravel/routes/web.php',
  51. 17
  52. );
  53. }
  54. public function testUserDeprecations()
  55. {
  56. $logger = m::mock(LogManager::class);
  57. $this->app->instance(LogManager::class, $logger);
  58. $logger->shouldReceive('channel')->with('deprecations')->andReturnSelf();
  59. $logger->shouldReceive('warning')->with(sprintf('%s in %s on line %s',
  60. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  61. '/home/user/laravel/routes/web.php',
  62. 17
  63. ));
  64. $this->handleExceptions->handleError(
  65. E_USER_DEPRECATED,
  66. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  67. '/home/user/laravel/routes/web.php',
  68. 17
  69. );
  70. }
  71. public function testErrors()
  72. {
  73. $logger = m::mock(LogManager::class);
  74. $this->app->instance(LogManager::class, $logger);
  75. $logger->shouldNotReceive('channel');
  76. $logger->shouldNotReceive('warning');
  77. $this->expectException(ErrorException::class);
  78. $this->expectExceptionMessage('Something went wrong');
  79. $this->handleExceptions->handleError(
  80. E_ERROR,
  81. 'Something went wrong',
  82. '/home/user/laravel/src/Providers/AppServiceProvider.php',
  83. 17
  84. );
  85. }
  86. public function testEnsuresDeprecationsDriver()
  87. {
  88. $logger = m::mock(LogManager::class);
  89. $this->app->instance(LogManager::class, $logger);
  90. $logger->shouldReceive('channel')->andReturnSelf();
  91. $logger->shouldReceive('warning');
  92. $this->config->set('logging.channels.stack', [
  93. 'driver' => 'stack',
  94. 'channels' => ['single'],
  95. 'ignore_exceptions' => false,
  96. ]);
  97. $this->config->set('logging.deprecations', 'stack');
  98. $this->handleExceptions->handleError(
  99. E_USER_DEPRECATED,
  100. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  101. '/home/user/laravel/routes/web.php',
  102. 17
  103. );
  104. $this->assertEquals(
  105. [
  106. 'driver' => 'stack',
  107. 'channels' => ['single'],
  108. 'ignore_exceptions' => false,
  109. ],
  110. $this->config->get('logging.channels.deprecations')
  111. );
  112. }
  113. public function testEnsuresNullDeprecationsDriver()
  114. {
  115. $logger = m::mock(LogManager::class);
  116. $this->app->instance(LogManager::class, $logger);
  117. $logger->shouldReceive('channel')->andReturnSelf();
  118. $logger->shouldReceive('warning');
  119. $this->handleExceptions->handleError(
  120. E_USER_DEPRECATED,
  121. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  122. '/home/user/laravel/routes/web.php',
  123. 17
  124. );
  125. $this->assertEquals(
  126. NullHandler::class,
  127. $this->config->get('logging.channels.deprecations.handler')
  128. );
  129. }
  130. public function testEnsuresNullLogDriver()
  131. {
  132. $logger = m::mock(LogManager::class);
  133. $this->app->instance(LogManager::class, $logger);
  134. $logger->shouldReceive('channel')->andReturnSelf();
  135. $logger->shouldReceive('warning');
  136. $this->handleExceptions->handleError(
  137. E_USER_DEPRECATED,
  138. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  139. '/home/user/laravel/routes/web.php',
  140. 17
  141. );
  142. $this->assertEquals(
  143. NullHandler::class,
  144. $this->config->get('logging.channels.deprecations.handler')
  145. );
  146. }
  147. public function testDoNotOverrideExistingNullLogDriver()
  148. {
  149. $logger = m::mock(LogManager::class);
  150. $this->app->instance(LogManager::class, $logger);
  151. $logger->shouldReceive('channel')->andReturnSelf();
  152. $logger->shouldReceive('warning');
  153. $this->config->set('logging.channels.null', [
  154. 'driver' => 'monolog',
  155. 'handler' => CustomNullHandler::class,
  156. ]);
  157. $this->handleExceptions->handleError(
  158. E_USER_DEPRECATED,
  159. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  160. '/home/user/laravel/routes/web.php',
  161. 17
  162. );
  163. $this->assertEquals(
  164. CustomNullHandler::class,
  165. $this->config->get('logging.channels.deprecations.handler')
  166. );
  167. }
  168. public function testNoDeprecationsDriverIfNoDeprecationsHereSend()
  169. {
  170. $this->assertEquals(null, $this->config->get('logging.deprecations'));
  171. $this->assertEquals(null, $this->config->get('logging.channels.deprecations'));
  172. }
  173. public function testIgnoreDeprecationIfLoggerUnresolvable()
  174. {
  175. $this->handleExceptions->handleError(
  176. E_DEPRECATED,
  177. 'str_contains(): Passing null to parameter #2 ($needle) of type string is deprecated',
  178. '/home/user/laravel/routes/web.php',
  179. 17
  180. );
  181. }
  182. }
  183. class CustomNullHandler extends NullHandler
  184. {
  185. }