Completed
Push — issue#666 ( 5e6b12...7229dc )
by Guilherme
09:55
created

RemoteClaimFetcherTest::testFetchByUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\RemoteClaimsBundle\Tests\Fetcher;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use GuzzleHttp\Client;
15
use GuzzleHttp\Message\Request;
16
use GuzzleHttp\Subscriber\History;
17
use GuzzleHttp\Subscriber\Mock;
18
use LoginCidadao\OAuthBundle\Entity\ClientRepository;
19
use LoginCidadao\OAuthBundle\Model\ClientInterface;
20
use LoginCidadao\RemoteClaimsBundle\Entity\RemoteClaim;
21
use LoginCidadao\RemoteClaimsBundle\Entity\RemoteClaimRepository;
22
use LoginCidadao\RemoteClaimsBundle\Fetcher\RemoteClaimFetcher;
23
use LoginCidadao\RemoteClaimsBundle\Model\HttpUri;
24
use LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimInterface;
25
use LoginCidadao\RemoteClaimsBundle\Model\TagUri;
26
use LoginCidadao\RemoteClaimsBundle\Tests\Parser\RemoteClaimParserTest;
27
28
class RemoteClaimFetcherTest extends \PHPUnit_Framework_TestCase
29
{
30
    public function testFetchByUri()
31
    {
32
        $this->runTestFetch('https://dummy.com');
33
    }
34
35
    public function testFetchByUriObject()
36
    {
37
        $this->runTestFetch(HttpUri::createFromString('https://dummy.com'));
38
    }
39
40
    public function testFetchByTag()
41
    {
42
        $data = RemoteClaimParserTest::$claimMetadata;
43
44
        $this->runTestFetch($data['claim_name'], 'https://dummy.com');
45
    }
46
47
    public function testFetchByTagObject()
48
    {
49
        $data = RemoteClaimParserTest::$claimMetadata;
50
51
        $this->runTestFetch(TagUri::createFromString($data['claim_name']), 'https://dummy.com');
52
    }
53
54
    public function testDiscoveryFailure()
55
    {
56
        $this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
57
        $data = RemoteClaimParserTest::$claimMetadata;
58
        $data['claim_name'] = 'tag:example.com,2017:my_claim';
59
60
        $this->runTestFetch(TagUri::createFromString('tag:example.com,2018:my_claim'), 'https://dummy.com');
61
    }
62
63
    public function testGetNewRemoteClaim()
64
    {
65
        $uri = 'https://dummy.com';
66
        $data = RemoteClaimParserTest::$claimMetadata;
67
        $history = new History();
68
69
        $httpClient = $this->getHttpClient($data, $history);
70
        $em = $this->getEntityManager();
71
        $em->expects($this->exactly(2))->method('persist')->willReturnCallback(function ($entity) {
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\ORM\EntityManagerInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
72
            if (!$entity instanceof ClientInterface
73
                && !$entity instanceof RemoteClaimInterface) {
74
                $this->fail('Expected ClientInterface or RemoteClaimInterface to be persisted.');
75
            }
76
        });
77
        $em->expects($this->once())->method('flush');
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Doctrine\ORM\EntityManagerInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
78
79
        $remoteClaimRepo = $this->getRemoteClaimRepository();
80
        $clientRepo = $this->getClientRepository();
81
82
        $fetcher = new RemoteClaimFetcher($httpClient, $em, $remoteClaimRepo, $clientRepo);
0 ignored issues
show
Bug introduced by
It seems like $em defined by $this->getEntityManager() on line 70 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<Doctrine\ORM\EntityManagerInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $remoteClaimRepo defined by $this->getRemoteClaimRepository() on line 79 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<LoginCidadao\Remo...\RemoteClaimRepository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $clientRepo defined by $this->getClientRepository() on line 80 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<LoginCidadao\OAut...ntity\ClientRepository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
83
        $fetcher->getRemoteClaim($uri);
84
    }
85
86
    public function testGetExistingRemoteClaim()
87
    {
88
        $uri = 'https://dummy.com';
89
        $data = RemoteClaimParserTest::$claimMetadata;
90
        $history = new History();
91
92
        $remoteClaim = $this->getMock('LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimInterface');
93
94
        $httpClient = $this->getHttpClient($data, $history);
95
        $em = $this->getEntityManager();
96
        $remoteClaimRepo = $this->getRemoteClaimRepository();
97
        $remoteClaimRepo->expects($this->once())->method('findOneBy')->willReturn($remoteClaim);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in LoginCidadao\RemoteClaim...y\RemoteClaimRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
98
        $clientRepo = $this->getClientRepository();
99
100
        $fetcher = new RemoteClaimFetcher($httpClient, $em, $remoteClaimRepo, $clientRepo);
0 ignored issues
show
Bug introduced by
It seems like $em defined by $this->getEntityManager() on line 95 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<Doctrine\ORM\EntityManagerInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $remoteClaimRepo defined by $this->getRemoteClaimRepository() on line 96 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<LoginCidadao\Remo...\RemoteClaimRepository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $clientRepo defined by $this->getClientRepository() on line 98 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<LoginCidadao\OAut...ntity\ClientRepository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
101
        $this->assertEquals($remoteClaim, $fetcher->getRemoteClaim($uri));
102
    }
103
104
    private function runTestFetch($uri, $expectedUri = null)
105
    {
106
        $data = RemoteClaimParserTest::$claimMetadata;
107
108
        /** @var History $history */
109
        $history = new History();
110
111
        $httpClient = $this->getHttpClient($data, $history, $expectedUri);
112
        $em = $this->getEntityManager();
113
        $remoteClaimRepo = $this->getRemoteClaimRepository();
114
        $clientRepo = $this->getClientRepository();
115
116
        $fetcher = new RemoteClaimFetcher($httpClient, $em, $remoteClaimRepo, $clientRepo);
0 ignored issues
show
Bug introduced by
It seems like $em defined by $this->getEntityManager() on line 112 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<Doctrine\ORM\EntityManagerInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $remoteClaimRepo defined by $this->getRemoteClaimRepository() on line 113 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<LoginCidadao\Remo...\RemoteClaimRepository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $clientRepo defined by $this->getClientRepository() on line 114 can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, LoginCidadao\RemoteClaim...mFetcher::__construct() does only seem to accept object<LoginCidadao\OAut...ntity\ClientRepository>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
117
        $remoteClaim = $fetcher->fetchRemoteClaim($uri);
118
119
        $this->assertEquals($data['claim_name'], $remoteClaim->getName());
120
121
        /** @var Request $request */
122
        $request = $history->getRequests()[$expectedUri ? 1 : 0];
123
        $this->assertEquals($expectedUri ?: $uri, $request->getUrl());
124
    }
125
126
    private function getHttpClient($data, &$history, $expectedUri = null)
127
    {
128
        $client = new Client();
129
130
        $metadata = json_encode($data);
131
        $length = strlen($metadata);
132
133
        $responses = ["HTTP/1.1 200 OK\r\n\Content-Length: {$length}\r\n\r\n{$metadata}"];
134
135
        if ($expectedUri) {
136
            $discoveryResponse = json_encode([
137
                'subject' => $data['claim_name'],
138
                'links' => [
139
                    ['rel' => 'http://openid.net/specs/connect/1.0/claim', 'href' => $expectedUri],
140
                ],
141
            ]);
142
            $discoveryLen = strlen($discoveryResponse);
143
            array_unshift($responses,
144
                "HTTP/1.1 200 OK\r\n\Content-Length: {$discoveryLen}\r\n\r\n{$discoveryResponse}");
145
        }
146
147
        $mock = new Mock($responses);
148
        $client->getEmitter()->attach($history);
149
        $client->getEmitter()->attach($mock);
150
151
        return $client;
152
    }
153
154
    /**
155
     * @return \PHPUnit_Framework_MockObject_MockObject|EntityManagerInterface
156
     */
157
    private function getEntityManager()
158
    {
159
        $em = $this->getMock('Doctrine\ORM\EntityManagerInterface');
160
161
        return $em;
162
    }
163
164
    /**
165
     * @return \PHPUnit_Framework_MockObject_MockObject|RemoteClaimRepository
166
     */
167
    private function getRemoteClaimRepository()
168
    {
169
        $repo = $this->getMockBuilder('LoginCidadao\RemoteClaimsBundle\Entity\RemoteClaimRepository')
170
            ->disableOriginalConstructor()->getMock();
171
172
        return $repo;
173
    }
174
175
    /**
176
     * @return ClientRepository|\PHPUnit_Framework_MockObject_MockObject
177
     */
178
    private function getClientRepository()
179
    {
180
        $repo = $this->getMockBuilder('LoginCidadao\OAuthBundle\Entity\ClientRepository')
181
            ->disableOriginalConstructor()->getMock();
182
183
        return $repo;
184
    }
185
}
186