Passed
Pull Request — master (#653)
by Aleksei
05:48
created

DispatcherTest::testServe()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 24
nc 1
nop 0
dl 0
loc 42
rs 9.536
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Tests\Framework\GRPC;
13
14
use Mockery as m;
15
use Spiral\Files\Files;
16
use Spiral\GRPC\GRPCDispatcher;
17
use Spiral\RoadRunner\Worker;
18
use Spiral\App\Service\Sub\Message;
19
use Spiral\Tests\Framework\ConsoleTest;
20
21
/**
22
 * WARNING: spiral/php-grpc not compatible with PHP 8.0
23
 *
24
 * @see https://github.com/spiral/php-grpc/issues/53
25
 * @requires PHP <= 7.4
26
 */
27
class DispatcherTest extends ConsoleTest
28
{
29
    public function setUp(): void
30
    {
31
        exec('protoc 2>&1', $out);
32
        if (strpos(implode("\n", $out), '--php_out') === false) {
33
            $this->markTestSkipped('Protoc binary is missing');
34
        }
35
36
        parent::setUp();
37
38
        $fs = new Files();
39
40
        $this->runCommandDebug('grpc:generate', [
41
            'proto' => realpath($fs->normalizePath($this->app->dir('app') . 'proto/service.proto'))
42
        ]);
43
44
        $output = $this->app->dir('app') . 'src/Service/EchoService.php';
45
        file_put_contents($output, GenerateTest::SERVICE);
46
    }
47
48
    public function tearDown(): void
49
    {
50
        parent::tearDown();
51
52
        $fs = new Files();
53
54
        if ($fs->isDirectory($this->app->dir('app') . 'src/Service')) {
55
            $fs->deleteDirectory($this->app->dir('app') . 'src/Service');
56
        }
57
58
        if ($fs->isDirectory($this->app->dir('app') . 'src/GPBMetadata')) {
59
            $fs->deleteDirectory($this->app->dir('app') . 'src/GPBMetadata');
60
        }
61
    }
62
63
    public function testCanServe(): void
64
    {
65
        $this->assertFalse($this->app->get(GRPCDispatcher::class)->canServe());
66
    }
67
68
    public function testCanServe2(): void
69
    {
70
        $this->app->getEnvironment()->set('RR_GRPC', true);
71
        $this->assertTrue($this->app->get(GRPCDispatcher::class)->canServe());
72
    }
73
74
    public function testServe(): void
75
    {
76
        $w = m::mock(Worker::class);
77
78
        $this->app->getEnvironment()->set('RR_GRPC', true);
79
        $this->app->getContainer()->bind(Worker::class, $w);
80
81
        $msg = new Message();
82
        $msg->setMsg('hello');
83
84
        $w->shouldReceive('receive')->once()->with(
85
            \Mockery::on(function (&$context) {
86
                $context = '{
87
                  "service": "service.Echo",
88
                  "method": "Ping",
89
                  "context": {}
90
                }';
91
92
                return true;
93
            })
94
        )->andReturn($msg->serializeToString());
95
96
        $w->shouldReceive('send')->once()->with(
97
            \Mockery::on(function ($out) {
98
                $msg = new Message();
99
                $msg->mergeFromString($out);
100
                $this->assertSame('hello', $msg->getMsg());
101
102
                return true;
103
            }),
104
            '{}'
105
        )->andReturn(true);
106
107
        // one command only
108
        $w->shouldReceive('receive')->once()->with(
109
            \Mockery::on(function (&$context) {
110
                $context = null;
111
                return true;
112
            })
113
        )->andReturn(null);
114
115
        $this->app->get(GRPCDispatcher::class)->serve();
116
    }
117
118
    public function testError(): void
119
    {
120
        $w = m::mock(Worker::class);
121
122
        $this->app->getEnvironment()->set('RR_GRPC', true);
123
        $this->app->getContainer()->bind(Worker::class, $w);
124
125
        $msg = new Message();
126
        $msg->setMsg('hello');
127
128
        $w->shouldReceive('receive')->once()->with(
129
            \Mockery::on(function (&$context) {
130
                $context = '{
131
                  "service": "service.Echo",
132
                  "method": "Invalid",
133
                  "context": {}
134
                }';
135
136
                return true;
137
            })
138
        )->andReturn($msg->serializeToString());
139
140
        $w->shouldReceive('error')->once()->with(
141
            \Mockery::on(function ($out) {
142
                $this->assertStringContainsString('Method `Invalid` not found', $out);
143
                return true;
144
            })
145
        )->andReturn(true);
146
147
        // one command only
148
        $w->shouldReceive('receive')->once()->with(
149
            \Mockery::on(function (&$context) {
150
                $context = null;
151
                return true;
152
            })
153
        )->andReturn(null);
154
155
        $this->app->get(GRPCDispatcher::class)->serve();
156
    }
157
}
158