Completed
Push — master ( ba7f7c...c7ee1c )
by Eugene
10:02
created

BoxErrorTest::testExceptionIsThrownOnBoxError()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the Tarantool Client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Tests\Integration;
15
16
use Tarantool\Client\Error;
17
use Tarantool\Client\Exception\RequestFailed;
18
19
final class BoxErrorTest extends TestCase
20
{
21
    public function testExceptionIsThrown() : void
22
    {
23
        $this->expectException(RequestFailed::class);
24
        $this->expectExceptionMessage('Because I can');
25
        $this->expectExceptionCode(42);
26
27
        $this->client->evaluate('box.error({code = 42, reason = "Because I can"})');
28
    }
29
30
    /**
31
     * @requires Tarantool >=2.4.1
32
     */
33
    public function testExceptionWithErrorIsThrown() : void
34
    {
35
        try {
36
            /*
37
             * Triggers "AccessDeniedError", which includes the fields
38
             * "object_type", "object_name" and "access_type".
39
             * See https://www.tarantool.io/en/doc/2.4/dev_guide/internals/box_protocol/#binary-protocol-responses-for-errors-extra.
40
             */
41
            $this->client->evaluate("
42
                local temp_user = 'user_with_no_privileges'
43
                local curr_user = box.session.user()
44
                box.schema.user.create(temp_user)
45
                box.session.su(temp_user)
46
                local _, err = pcall(box.schema.user.grant, temp_user, 'execute', 'universe')
47
                box.session.su(curr_user)
48
                box.schema.user.drop(temp_user)
49
                box.error(err)
50
            ");
51
            self::fail(sprintf('"%s" exception was not thrown', RequestFailed::class));
52
        } catch (RequestFailed $e) {
53
            self::assertSame("Write access to space '_priv' is denied for user 'user_with_no_privileges'", $e->getMessage());
54
            self::assertSame(42, $e->getCode());
55
56
            $error = $e->getError();
57
            self::assertInstanceOf(Error::class, $error);
58
            self::assertSame('AccessDeniedError', $error->getType());
59
            self::assertSame("Write access to space '_priv' is denied for user 'user_with_no_privileges'", $error->getMessage());
60
            self::assertSame(42, $error->getCode());
61
            self::assertEquals([
62
                'object_type' => 'space',
63
                'object_name' => '_priv',
64
                'access_type' => 'Write',
65
            ], $error->getFields());
66
            self::assertNull($error->getPrevious());
67
        }
68
    }
69
70
    /**
71
     * @requires Tarantool >=2.4.1
72
     */
73
    public function testExceptionWithNestedErrorIsThrown() : void
74
    {
75
        try {
76
            $this->client->evaluate('
77
                err1 = box.error.new({code = 1, type = "t1", reason = "r1"})
78
                err2 = box.error.new({code = 2, type = "t2", reason = "r2",})
79
                err1:set_prev(err2)
80
                box.error(err1)
81
            ');
82
            self::fail(sprintf('"%s" exception was not thrown', RequestFailed::class));
83
        } catch (RequestFailed $e) {
84
            self::assertSame('r1', $e->getMessage());
85
            self::assertSame(1, $e->getCode());
86
87
            $error = $e->getError();
88
            self::assertInstanceOf(Error::class, $error);
89
            self::assertSame('CustomError', $error->getType());
90
            self::assertSame('r1', $error->getMessage());
91
            self::assertSame(1, $error->getCode());
92
            self::assertSame(['custom_type' => 't1'], $error->getFields());
93
94
            $prevError = $error->getPrevious();
95
            self::assertInstanceOf(Error::class, $prevError);
96
            self::assertSame('CustomError', $prevError->getType());
97
            self::assertSame('r2', $prevError->getMessage());
98
            self::assertSame(2, $prevError->getCode());
99
            self::assertSame(['custom_type' => 't2'], $prevError->getFields());
100
            self::assertNull($prevError->getPrevious());
101
        }
102
    }
103
}
104