RestErrorHandlingTest.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. /**
  3. * Test Web API error codes.
  4. *
  5. * Copyright © Magento, Inc. All rights reserved.
  6. * See COPYING.txt for license details.
  7. */
  8. namespace Magento\Webapi\Routing;
  9. use Magento\TestFramework\Helper\Bootstrap;
  10. use Magento\Framework\Webapi\Exception as WebapiException;
  11. class RestErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstract
  12. {
  13. /**
  14. * @var string
  15. */
  16. protected $mode;
  17. protected function setUp()
  18. {
  19. $this->_markTestAsRestOnly();
  20. $this->mode = Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class)->getMode();
  21. parent::setUp();
  22. }
  23. public function testSuccess()
  24. {
  25. $serviceInfo = [
  26. 'rest' => [
  27. 'resourcePath' => '/V1/errortest/success',
  28. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  29. ],
  30. ];
  31. $item = $this->_webApiCall($serviceInfo);
  32. // TODO: check Http Status = 200, cannot do yet due to missing header info returned
  33. $this->assertEquals('a good id', $item['value'], 'Success case is correct');
  34. }
  35. public function testNotFound()
  36. {
  37. $serviceInfo = [
  38. 'rest' => [
  39. 'resourcePath' => '/V1/errortest/notfound',
  40. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  41. ],
  42. ];
  43. // \Magento\Framework\Api\ResourceNotFoundException
  44. $this->_errorTest(
  45. $serviceInfo,
  46. ['resourceY'],
  47. WebapiException::HTTP_NOT_FOUND,
  48. 'Resource with ID "%1" not found.'
  49. );
  50. }
  51. public function testUnauthorized()
  52. {
  53. $serviceInfo = [
  54. 'rest' => [
  55. 'resourcePath' => '/V1/errortest/unauthorized',
  56. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  57. ],
  58. ];
  59. // \Magento\Framework\Api\AuthorizationException
  60. $this->_errorTest(
  61. $serviceInfo,
  62. [],
  63. WebapiException::HTTP_UNAUTHORIZED,
  64. "The consumer isn't authorized to access %1.",
  65. ['resourceN']
  66. );
  67. }
  68. public function testOtherException()
  69. {
  70. $serviceInfo = [
  71. 'rest' => [
  72. 'resourcePath' => '/V1/errortest/otherException',
  73. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  74. ],
  75. ];
  76. /* TODO : Fix as part MAGETWO-31330
  77. $expectedMessage = $this->mode == \Magento\Framework\App\State::MODE_DEVELOPER
  78. ? 'Non service exception'
  79. : 'Internal Error. Details are available in Magento log file. Report ID: webapi-XXX';
  80. */
  81. $expectedMessage = 'Internal Error. Details are available in Magento log file. Report ID: webapi-XXX';
  82. $this->_errorTest(
  83. $serviceInfo,
  84. [],
  85. WebapiException::HTTP_INTERNAL_ERROR,
  86. $expectedMessage,
  87. null,
  88. 'Magento\TestModule3\Service\V1\Error->otherException()' // Check if trace contains proper error source
  89. );
  90. }
  91. /**
  92. * Perform a negative REST api call test case and compare the results with expected values.
  93. *
  94. * @param string $serviceInfo - REST Service information (i.e. resource path and HTTP method)
  95. * @param array $data - Data for the cal
  96. * @param int $httpStatus - Expected HTTP status
  97. * @param string|array $errorMessage - \Exception error message
  98. * @param array $parameters - Optional parameters array, or null if no parameters
  99. * @param string $traceString - Optional trace string to verify
  100. */
  101. protected function _errorTest(
  102. $serviceInfo,
  103. $data,
  104. $httpStatus,
  105. $errorMessage,
  106. $parameters = [],
  107. $traceString = null
  108. ) {
  109. try {
  110. $this->_webApiCall($serviceInfo, $data);
  111. } catch (\Exception $e) {
  112. $this->assertEquals($httpStatus, $e->getCode(), 'Checking HTTP status code');
  113. $body = json_decode($e->getMessage(), true);
  114. $errorMessages = is_array($errorMessage) ? $errorMessage : [$errorMessage];
  115. $actualMessage = $body['message'];
  116. $matches = [];
  117. //Report ID was created dynamically, so we need to replace it with some static value in order to test
  118. if (preg_match('/.*Report\sID\:\s([a-zA-Z0-9\-]*)/', $actualMessage, $matches)) {
  119. $actualMessage = str_replace($matches[1], 'webapi-XXX', $actualMessage);
  120. }
  121. //make sure that the match for a report with an id is found if Internal error was reported
  122. //Refer : \Magento\Framework\Webapi\ErrorProcessor::INTERNAL_SERVER_ERROR_MSG
  123. if (count($matches) > 1) {
  124. $this->assertTrue(!empty($matches[1]), 'Report id missing for internal error.');
  125. }
  126. $this->assertContains(
  127. $actualMessage,
  128. $errorMessages,
  129. "Message is invalid. Actual: '{$actualMessage}'. Expected one of: {'" . implode(
  130. "', '",
  131. $errorMessages
  132. ) . "'}"
  133. );
  134. if ($parameters) {
  135. $this->assertEquals($parameters, $body['parameters'], 'Checking body parameters');
  136. }
  137. if ($this->mode == \Magento\Framework\App\State::MODE_DEVELOPER && $traceString) {
  138. // TODO : Fix as part MAGETWO-31330
  139. //$this->assertContains($traceString, $body['trace'], 'Trace information is incorrect.');
  140. }
  141. }
  142. }
  143. }