Passed
Push — master ( 1e427b...ae9ba8 )
by Daniel
01:54
created

MethodDispatcherTest   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 63
c 0
b 0
f 0
dl 0
loc 99
rs 10
wmc 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Usox\JsonSchemaApi\Dispatch;
6
7
use Mockery;
8
use Mockery\Adapter\Phpunit\MockeryTestCase;
9
use Mockery\MockInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use Teapot\StatusCode;
12
use Usox\JsonSchemaApi\Contract\ApiMethodInterface;
13
use Usox\JsonSchemaApi\Contract\MethodProviderInterface;
14
use Usox\JsonSchemaApi\Exception\MethodNotFoundException;
15
16
class MethodDispatcherTest extends MockeryTestCase
17
{
18
    /** @var MockInterface|SchemaLoaderInterface */
19
    private MockInterface $schemaLoader;
20
    
21
    /** @var MethodValidatorInterface|MockInterface */
22
    private MockInterface $methodValidator;
23
24
    /** @var MethodProviderInterface|MockInterface */
25
    private MockInterface $methodProvider;
26
    
27
    private MethodDispatcher $subject;
28
    
29
    public function setUp(): void
30
    {
31
        $this->schemaLoader = Mockery::mock(SchemaLoaderInterface::class);
32
        $this->methodValidator = Mockery::mock(MethodValidatorInterface::class);
33
        $this->methodProvider = Mockery::mock(MethodProviderInterface::class);
34
        
35
        $this->subject = new MethodDispatcher(
36
            $this->schemaLoader,
37
            $this->methodValidator,
38
            $this->methodProvider
39
        );
40
    }
41
    
42
    public function testDispatchThrowsExceptionIfMethodDoesNotExist(): void
43
    {
44
        $request = Mockery::mock(ServerRequestInterface::class);
45
        
46
        $this->expectException(MethodNotFoundException::class);
47
        $this->expectExceptionMessage('Method not found');
48
        $this->expectExceptionCode(StatusCode::BAD_REQUEST);
49
        
50
        $method = 'some-method';
51
        $version = null;
52
        
53
        $input = ['method' => $method, 'version' => $version];
54
        
55
        $this->methodProvider->shouldReceive('lookup')
56
            ->with($method)
57
            ->once()
58
            ->andReturnNull();
59
        
60
        $this->subject->dispatch(
61
            $request,
62
            (object) $input
63
        );
64
    }
65
66
    public function testDispatchReturnsHandler(): void
67
    {
68
        $method = 'some-method';
69
        $version = 666;
70
        $result = ['some-result'];
71
        $parameter = (object) ['some-parameter'];
72
        $schemaContent = (object) ['some' => 'schema-content'];
73
        $schemaFilePath = 'some-path';
74
75
        $input = (object) ['method' => $method, 'version' => $version, 'parameter' => $parameter];
76
77
        $request = Mockery::mock(ServerRequestInterface::class);
78
        $handler = Mockery::mock(ApiMethodInterface::class);
79
        
80
        $handler->shouldReceive('getSchemaFile')
81
            ->withNoArgs()
82
            ->once()
83
            ->andReturn($schemaFilePath);
84
        
85
        $this->schemaLoader->shouldReceive('load')
86
            ->with($schemaFilePath)
87
            ->once()
88
            ->andReturn($schemaContent);
89
90
        $this->methodProvider->shouldReceive('lookup')
91
            ->with(sprintf('%s.%d', $method, $version))
92
            ->once()
93
            ->andReturn($handler);
94
        
95
        $this->methodValidator->shouldReceive('validateInput')
96
            ->with($schemaContent, $input)
97
            ->once();
98
        $this->methodValidator->shouldReceive('validateOutput')
99
            ->with(
100
                $schemaContent,
101
                Mockery::on(function ($param) use ($result): bool {
102
                    return (array) $param == $result;
103
                })
104
            )
105
            ->once();
106
        
107
        $handler->shouldReceive('handle')
108
            ->with($request, $parameter)
109
            ->once()
110
            ->andReturn($result);
111
        
112
        static::assertSame(
113
            $result,
114
            $this->subject->dispatch($request, $input)
115
        );
116
    }
117
}
118