ClientTest   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 152
rs 10
c 0
b 0
f 0
wmc 6

6 Methods

Rating   Name   Duplication   Size   Complexity  
A testThrowsRuntimeExceptionOnMissingPeers() 0 3 1
B testProcessSignedProposalHandlesConnectionError() 0 24 1
A testChannelWrapsException() 0 6 1
A testGetChannel() 0 6 1
B setUp() 0 44 1
A testProcessProposal() 0 20 1
1
<?php
2
3
/**
4
 * Copyright 2017 American Express Travel Related Services Company, Inc.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
15
 * or implied. See the License for the specific language governing
16
 * permissions and limitations under the License.
17
 */
18
19
declare(strict_types=1);
20
21
namespace AmericanExpressTest\HyperledgerFabricClient;
22
23
use AmericanExpress\HyperledgerFabricClient\Channel\ChannelFactoryInterface;
24
use AmericanExpress\HyperledgerFabricClient\Channel\ChannelInterface;
25
use AmericanExpress\HyperledgerFabricClient\Client;
26
use AmericanExpress\HyperledgerFabricClient\EndorserClient\EndorserClientManagerInterface;
27
use AmericanExpress\HyperledgerFabricClient\Exception\InvalidArgumentException;
28
use AmericanExpress\HyperledgerFabricClient\Exception\RuntimeException;
29
use AmericanExpress\HyperledgerFabricClient\Organization\OrganizationOptions;
30
use AmericanExpress\HyperledgerFabricClient\Peer\Peer;
31
use AmericanExpress\HyperledgerFabricClient\Peer\PeerInterface;
32
use AmericanExpress\HyperledgerFabricClient\Proposal\ResponseCollection;
33
use AmericanExpress\HyperledgerFabricClient\Signatory\SignatoryInterface;
34
use AmericanExpress\HyperledgerFabricClient\Transaction\TransactionOptions;
35
use AmericanExpress\HyperledgerFabricClient\User\UserContext;
36
use Grpc\UnaryCall;
37
use Hyperledger\Fabric\Protos\MSP\SerializedIdentity;
38
use Hyperledger\Fabric\Protos\Peer\EndorserClient;
39
use Hyperledger\Fabric\Protos\Peer\Proposal;
40
use Hyperledger\Fabric\Protos\Peer\ProposalResponse;
41
use PHPUnit\Framework\TestCase;
42
43
/**
44
 * @covers \AmericanExpress\HyperledgerFabricClient\Client
45
 */
46
class ClientTest extends TestCase
47
{
48
    /**
49
     * @var ChannelFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
50
     */
51
    private $channelFactory;
52
53
    /**
54
     * @var PeerInterface
55
     */
56
    private $peer;
57
58
    /**
59
     * @var UnaryCall|\PHPUnit_Framework_MockObject_MockObject
60
     */
61
    private $unaryCall;
62
63
    /**
64
     * @var SignatoryInterface|\PHPUnit_Framework_MockObject_MockObject
65
     */
66
    private $signatory;
67
68
    /**
69
     * @var EndorserClient|\PHPUnit_Framework_MockObject_MockObject
70
     */
71
    private $endorserClient;
72
73
    /**
74
     * @var Client
75
     */
76
    private $sut;
77
78
    protected function setUp()
79
    {
80
        $this->endorserClient = $this->getMockBuilder(EndorserClient::class)
81
            ->disableOriginalConstructor()
82
            ->getMock();
83
84
        $this->peer = new Peer($this->endorserClient);
85
86
        /** @var EndorserClientManagerInterface|\PHPUnit_Framework_MockObject_MockObject $endorserClients */
87
        $endorserClients = $this->getMockBuilder(EndorserClientManagerInterface::class)
88
            ->getMock();
89
90
        $endorserClients->method('get')
0 ignored issues
show
Bug introduced by
The method method() does not exist on AmericanExpress\Hyperled...rClientManagerInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

90
        $endorserClients->/** @scrutinizer ignore-call */ 
91
                          method('get')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
91
            ->willReturn($this->endorserClient);
92
93
        $this->signatory = $this->getMockBuilder(SignatoryInterface::class)
94
            ->getMock();
95
96
        $this->unaryCall = $this->getMockBuilder(UnaryCall::class)
97
            ->disableOriginalConstructor()
98
            ->getMock();
99
100
        $identity = new SerializedIdentity();
101
102
        $user = new UserContext($identity, new OrganizationOptions([
103
            'peers' => [
104
                [
105
                    'name' => 'peer1',
106
                    'requests' => 'localhost:7051',
107
                    'events' => 'localhost:7053',
108
                    'server-hostname' => 'peer0.org1.example.com',
109
                    'tls_cacerts' => __FILE__,
110
                ],
111
            ],
112
            'privateKey' => __FILE__,
113
        ]));
114
115
        $this->channelFactory = $this->getMockBuilder(ChannelFactoryInterface::class)
116
            ->getMock();
117
118
        $this->sut = new Client(
119
            $user,
120
            $this->signatory,
121
            $this->channelFactory
122
        );
123
    }
124
125
    public function testGetChannel()
126
    {
127
        $result = $this->sut->getChannel('foo');
128
129
        self::assertInstanceOf(ChannelInterface::class, $result);
130
        self::assertSame($result, $this->sut->getChannel('foo'));
131
    }
132
133
    /**
134
     * @expectedException RuntimeException
135
     */
136
    public function testChannelWrapsException()
137
    {
138
        $this->channelFactory->method('create')
0 ignored issues
show
Bug introduced by
The method method() does not exist on AmericanExpress\Hyperled...ChannelFactoryInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

138
        $this->channelFactory->/** @scrutinizer ignore-call */ 
139
                               method('create')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
            ->willThrowException(new InvalidArgumentException());
140
141
        $this->sut->getChannel('foo');
142
    }
143
144
    public function testProcessProposal()
145
    {
146
        $this->endorserClient->method('ProcessProposal')
0 ignored issues
show
Bug introduced by
The method method() does not exist on Hyperledger\Fabric\Protos\Peer\EndorserClient. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

146
        $this->endorserClient->/** @scrutinizer ignore-call */ 
147
                               method('ProcessProposal')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
147
            ->willReturn($this->unaryCall);
148
149
        $this->unaryCall->method('wait')
0 ignored issues
show
Bug introduced by
The method method() does not exist on Grpc\UnaryCall. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

149
        $this->unaryCall->/** @scrutinizer ignore-call */ 
150
                          method('wait')

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
150
            ->willReturn([
151
                new ProposalResponse(),
152
                [ 'code' => 0 ]
153
            ]);
154
155
        $context = new TransactionOptions([
156
            'peers' => [$this->peer],
157
        ]);
158
159
        $response = $this->sut->processProposal(new Proposal(), $context);
160
161
        self::assertInstanceOf(ResponseCollection::class, $response);
162
        self::assertCount(1, $response->getProposalResponses());
163
        self::assertCount(0, $response->getExceptions());
164
    }
165
166
    public function testProcessSignedProposalHandlesConnectionError()
167
    {
168
        $this->endorserClient->method('ProcessProposal')
169
            ->willReturn($this->unaryCall);
170
171
        $this->unaryCall->method('wait')
172
            ->willReturn([
173
                null,
174
                [
175
                    'code' => 14,
176
                    'details' => 'Connect failed',
177
                    'metadata' => [],
178
                ]
179
            ]);
180
181
        $context = new TransactionOptions([
182
            'peers' => [$this->peer],
183
        ]);
184
185
        $response = $this->sut->processProposal(new Proposal(), $context);
186
187
        self::assertInstanceOf(ResponseCollection::class, $response);
188
        self::assertCount(0, $response->getProposalResponses());
189
        self::assertCount(1, $response->getExceptions());
190
    }
191
192
    /**
193
     * @expectedException RuntimeException
194
     */
195
    public function testThrowsRuntimeExceptionOnMissingPeers()
196
    {
197
        $this->sut->processProposal(new Proposal(), new TransactionOptions());
198
    }
199
}
200