GetsSignedRequestTest   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 7

Importance

Changes 0
Metric Value
wmc 2
lcom 0
cbo 7
dl 0
loc 125
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B testPerformsX509IfPkiTypeNotNone() 0 59 1
B testGetsSignedRequest() 0 62 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bip70\Test\Client\GuzzleClient;
6
7
use Bip70\Client\GuzzleHttpClient;
8
use Bip70\Client\MIMEType;
9
use Bip70\Client\NetworkConfig\BitcoinNetworkConfig;
10
use Bip70\Client\PaymentRequestInfo;
11
use Bip70\Protobuf\Proto\PaymentDetails;
12
use Bip70\X509\PKIType;
13
use Bip70\X509\RequestSigner;
14
use Bip70\X509\RequestValidation;
15
use Bip70\X509\TrustStoreLoader;
16
use GuzzleHttp\Handler\MockHandler;
17
use GuzzleHttp\HandlerStack;
18
use GuzzleHttp\Middleware;
19
use GuzzleHttp\Psr7\Response;
20
use PHPUnit\Framework\TestCase;
21
use Psr\Http\Message\RequestInterface;
22
use Psr\Http\Message\ResponseInterface;
23
use Sop\CryptoEncoding\PEM;
24
use Sop\CryptoEncoding\PEMBundle;
25
use Sop\CryptoTypes\Asymmetric\PrivateKeyInfo;
26
use X509\Certificate\CertificateBundle;
27
use X509\CertificationPath\PathValidation\PathValidationConfig;
28
use X509\CertificationPath\PathValidation\PathValidationResult;
29
30
class GetsSignedRequestTest extends TestCase
31
{
32
    public function testPerformsX509IfPkiTypeNotNone()
33
    {
34
        $keySigned = PrivateKeyInfo::fromPEM(PEM::fromFile(__DIR__ . "/../../../data/testnet-only-cert-not-valid.key"));
35
        $certs = CertificateBundle::fromPEMBundle(PEMBundle::fromFile(__DIR__ . "/../../../data/testnet-only-cert-not-valid.cabundle.pem"));
36
        $certSigned = $certs->all()[0];
37
        $certBundle = new CertificateBundle(...array_slice($certs->all(), 1));
38
39
        $now = 1509692666;
40
        $details = new PaymentDetails();
41
        $details->setTime($now);
42
43
        $requestSigner = new RequestSigner();
44
        $request = $requestSigner->sign($details, PKIType::X509_SHA256, $keySigned, $certSigned, $certBundle);
45
        $serializedRequest = $request->serialize();
46
47
        $container = [];
48
        $history = Middleware::history($container);
49
50
        $handler = new MockHandler([
51
            // response to our GET PAYMENTREQUEST request
52
            new Response(200, [
53
                'Content-Type' => [
54
                    'application/bitcoin-paymentrequest',
55
                ]
56
            ], $serializedRequest)
57
        ]);
58
59
        $stack = HandlerStack::create($handler);
60
        $stack->push($history);
61
62
        $mockClient = new \GuzzleHttp\Client([
63
            'handler' => $stack,
64
        ]);
65
66
        $client = new GuzzleHttpClient($mockClient);
67
68
        $requestUrl = "https://development.bip70.local/invoice/1";
69
70
        $networkConfig = new BitcoinNetworkConfig();
71
72
        $validator = $this->getMockBuilder(RequestValidation::class)
73
            ->disableOriginalConstructor()
74
            ->getMock();
75
76
        $validator->expects($this->once())
77
            ->method('verifyX509Details')
78
            ->withAnyParameters()
79
            ->willReturnCallback(function () {
80
                return $this->getMockBuilder(PathValidationResult::class)
81
                    ->disableOriginalConstructor()
82
                    ->getMock();
83
            });
84
        $data = $client->getRequest($requestUrl, $validator, $networkConfig);
85
86
        $this->assertInstanceOf(PaymentRequestInfo::class, $data);
87
        $this->assertEquals($serializedRequest, $data->request()->serialize());
88
        $this->assertCount(1, $container);
89
        $this->assertInstanceOf(PathValidationResult::class, $data->pathValidation());
90
    }
91
92
    public function testGetsSignedRequest()
93
    {
94
        $keySigned = PrivateKeyInfo::fromPEM(PEM::fromFile(__DIR__ . "/../../../data/testnet-only-cert-not-valid.key"));
95
        $certs = CertificateBundle::fromPEMBundle(PEMBundle::fromFile(__DIR__ . "/../../../data/testnet-only-cert-not-valid.cabundle.pem"));
96
        $certSigned = $certs->all()[0];
97
        $certBundle = new CertificateBundle(...array_slice($certs->all(), 1));
98
99
        $now = 1509692666;
100
        $details = new PaymentDetails();
101
        $details->setTime($now);
102
103
        $requestSigner = new RequestSigner();
104
        $request = $requestSigner->sign($details, PKIType::X509_SHA256, $keySigned, $certSigned, $certBundle);
105
        $serializedRequest = $request->serialize();
106
107
        $container = [];
108
        $history = Middleware::history($container);
109
110
        $handler = new MockHandler([
111
            // response to our GET PAYMENTREQUEST request
112
            new Response(200, [
113
                'Content-Type' => [
114
                    'application/bitcoin-paymentrequest',
115
                ]
116
            ], $serializedRequest)
117
        ]);
118
119
        $stack = HandlerStack::create($handler);
120
        $stack->push($history);
121
122
        $mockClient = new \GuzzleHttp\Client([
123
            'handler' => $stack,
124
        ]);
125
126
        $client = new GuzzleHttpClient($mockClient);
127
128
        $requestUrl = "https://development.bip70.local/invoice/1";
129
130
        // 10/12/2017 ish
131
        $dtnow = new \DateTimeImmutable();
132
        $dtnow = $dtnow->setTimestamp($now);
133
        $networkConfig = new BitcoinNetworkConfig();
134
        $validationConfig = new PathValidationConfig($dtnow, 10);
135
        $validator = new RequestValidation($validationConfig, TrustStoreLoader::fromSystem());
136
        $data = $client->getRequest($requestUrl, $validator, $networkConfig);
137
138
        $this->assertInstanceOf(PaymentRequestInfo::class, $data);
139
        $this->assertEquals($serializedRequest, $data->request()->serialize());
140
        $this->assertCount(1, $container);
141
        $this->assertInstanceOf(PathValidationResult::class, $data->pathValidation());
142
143
        /** @var RequestInterface $req1 */
144
        $req1 = $container[0]['request'];
145
        $this->assertEquals($requestUrl, $req1->getUri());
146
        $this->assertTrue($req1->hasHeader('Accept'));
147
        $this->assertEquals($networkConfig->getPaymentRequestMimeType(), $req1->getHeader('Accept')[0]);
148
149
        /** @var ResponseInterface $res1 */
150
        $res1 = $container[0]['response'];
151
        $res1->getBody()->rewind();
152
        $this->assertEquals($serializedRequest, $res1->getBody()->getContents());
153
    }
154
}
155