RestErrorHandlingTest.php 5.54 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
<?php
/**
 * Test Web API error codes.
 *
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Magento\Webapi\Routing;

use Magento\TestFramework\Helper\Bootstrap;
use Magento\Framework\Webapi\Exception as WebapiException;

class RestErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstract
{
    /**
     * @var string
     */
    protected $mode;

    protected function setUp()
    {
        $this->_markTestAsRestOnly();
        $this->mode = Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class)->getMode();
        parent::setUp();
    }

    public function testSuccess()
    {
        $serviceInfo = [
            'rest' => [
                'resourcePath' => '/V1/errortest/success',
                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
            ],
        ];

        $item = $this->_webApiCall($serviceInfo);

        // TODO: check Http Status = 200, cannot do yet due to missing header info returned

        $this->assertEquals('a good id', $item['value'], 'Success case is correct');
    }

    public function testNotFound()
    {
        $serviceInfo = [
            'rest' => [
                'resourcePath' => '/V1/errortest/notfound',
                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
            ],
        ];

        // \Magento\Framework\Api\ResourceNotFoundException
        $this->_errorTest(
            $serviceInfo,
            ['resourceY'],
            WebapiException::HTTP_NOT_FOUND,
            'Resource with ID "%1" not found.'
        );
    }

    public function testUnauthorized()
    {
        $serviceInfo = [
            'rest' => [
                'resourcePath' => '/V1/errortest/unauthorized',
                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
            ],
        ];

        // \Magento\Framework\Api\AuthorizationException
        $this->_errorTest(
            $serviceInfo,
            [],
            WebapiException::HTTP_UNAUTHORIZED,
            "The consumer isn't authorized to access %1.",
            ['resourceN']
        );
    }

    public function testOtherException()
    {
        $serviceInfo = [
            'rest' => [
                'resourcePath' => '/V1/errortest/otherException',
                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
            ],
        ];

        /* TODO : Fix as part MAGETWO-31330
        $expectedMessage = $this->mode == \Magento\Framework\App\State::MODE_DEVELOPER
            ? 'Non service exception'
            : 'Internal Error. Details are available in Magento log file. Report ID: webapi-XXX';
        */
        $expectedMessage = 'Internal Error. Details are available in Magento log file. Report ID: webapi-XXX';
        $this->_errorTest(
            $serviceInfo,
            [],
            WebapiException::HTTP_INTERNAL_ERROR,
            $expectedMessage,
            null,
            'Magento\TestModule3\Service\V1\Error->otherException()' // Check if trace contains proper error source
        );
    }

    /**
     * Perform a negative REST api call test case and compare the results with expected values.
     *
     * @param string $serviceInfo - REST Service information (i.e. resource path and HTTP method)
     * @param array $data - Data for the cal
     * @param int $httpStatus - Expected HTTP status
     * @param string|array $errorMessage - \Exception error message
     * @param array $parameters - Optional parameters array, or null if no parameters
     * @param string $traceString - Optional trace string to verify
     */
    protected function _errorTest(
        $serviceInfo,
        $data,
        $httpStatus,
        $errorMessage,
        $parameters = [],
        $traceString = null
    ) {
        try {
            $this->_webApiCall($serviceInfo, $data);
        } catch (\Exception $e) {
            $this->assertEquals($httpStatus, $e->getCode(), 'Checking HTTP status code');

            $body = json_decode($e->getMessage(), true);

            $errorMessages = is_array($errorMessage) ? $errorMessage : [$errorMessage];
            $actualMessage = $body['message'];
            $matches = [];
            //Report ID was created dynamically, so we need to replace it with some static value in order to test
            if (preg_match('/.*Report\sID\:\s([a-zA-Z0-9\-]*)/', $actualMessage, $matches)) {
                $actualMessage = str_replace($matches[1], 'webapi-XXX', $actualMessage);
            }
            //make sure that the match for a report with an id is found if Internal error was reported
            //Refer : \Magento\Framework\Webapi\ErrorProcessor::INTERNAL_SERVER_ERROR_MSG
            if (count($matches) > 1) {
                $this->assertTrue(!empty($matches[1]), 'Report id missing for internal error.');
            }
            $this->assertContains(
                $actualMessage,
                $errorMessages,
                "Message is invalid. Actual: '{$actualMessage}'. Expected one of: {'" . implode(
                    "', '",
                    $errorMessages
                ) . "'}"
            );

            if ($parameters) {
                $this->assertEquals($parameters, $body['parameters'], 'Checking body parameters');
            }

            if ($this->mode == \Magento\Framework\App\State::MODE_DEVELOPER && $traceString) {
                // TODO : Fix as part MAGETWO-31330
                //$this->assertContains($traceString, $body['trace'], 'Trace information is incorrect.');
            }
        }
    }
}