Completed
Push — issue#804 ( 62fcb8 )
by Guilherme
04:14
created

CpfVerificationService::parseChallengesList()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 2
nop 1
dl 0
loc 12
ccs 8
cts 8
cp 1
crap 3
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 PROCERGS\LoginCidadao\CpfVerificationBundle\Service;
12
13
use GuzzleHttp\Client;
14
use PROCERGS\LoginCidadao\CpfVerificationBundle\Exception\CpfNotSubscribedToNfgException;
15
use PROCERGS\LoginCidadao\CpfVerificationBundle\Model\ChallengeInterface;
16
use PROCERGS\LoginCidadao\CpfVerificationBundle\Model\SelectMotherInitialsChallenge;
17
use PROCERGS\LoginCidadao\CpfVerificationBundle\Model\TypeBirthdayChallenge;
18
use PROCERGS\LoginCidadao\CpfVerificationBundle\Model\TypeMotherInitialsChallenge;
19
use PROCERGS\LoginCidadao\CpfVerificationBundle\Model\TypePostalCodeChallenge;
20
use PROCERGS\LoginCidadao\CpfVerificationBundle\Model\TypeVoterRegistrationChallenge;
21
use PROCERGS\LoginCidadao\CpfVerificationBundle\Parser\ChallengeParser;
22
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
23
24
class CpfVerificationService
25
{
26
    /** @var Client */
27
    private $client;
28
29
    /**
30
     * CpfVerificationService constructor.
31
     * @param Client $client
32
     */
33 3
    public function __construct(Client $client)
34
    {
35 3
        $this->client = $client;
36 3
    }
37
38
    /**
39
     * @param string $cpf
40
     * @return ChallengeInterface[]
41
     * @throws CpfNotSubscribedToNfgException
42
     */
43 1
    public function listAvailableChallenges(string $cpf): array
44
    {
45 1
        $challenges = $this->getAvailableChallengesFromApi($cpf);
46
47 1
        return $challenges;
48
49
        return [
0 ignored issues
show
Unused Code introduced by
return array(new PROCERG...tionChallenge(5, $cpf)) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
50
            new TypeMotherInitialsChallenge(1, $cpf),
51
            new SelectMotherInitialsChallenge(2, $cpf, ['ABC', 'DEF', 'XYZ']),
52
            new TypePostalCodeChallenge(3, $cpf),
53
            new TypeBirthdayChallenge(4, $cpf),
54
            new TypeVoterRegistrationChallenge(5, $cpf),
55
        ];
56
    }
57
58
    /**
59
     * @param ChallengeInterface $challenge
60
     * @return ChallengeInterface
61
     * @throws CpfNotSubscribedToNfgException
62
     */
63 1
    public function selectChallenge(ChallengeInterface $challenge): ChallengeInterface
64
    {
65 1
        return $this->selectChallengeFromApi($challenge);
66
67
        return $challenge;
0 ignored issues
show
Unused Code introduced by
return $challenge is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
68
    }
69
70
    /**
71
     * @param ChallengeInterface $challenge
72
     * @param $answer
73
     * @return bool
74
     * @throws CpfNotSubscribedToNfgException
75
     */
76 1
    public function answerChallenge(ChallengeInterface $challenge, $answer): bool
0 ignored issues
show
Unused Code introduced by
The parameter $answer is not used and could be removed. ( Ignorable by Annotation )

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

76
    public function answerChallenge(ChallengeInterface $challenge, /** @scrutinizer ignore-unused */ $answer): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $challenge is not used and could be removed. ( Ignorable by Annotation )

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

76
    public function answerChallenge(/** @scrutinizer ignore-unused */ ChallengeInterface $challenge, $answer): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
77
    {
78
        // TODO: implement actual method
79
80 1
        return true;
81
    }
82
83 1
    private function getAvailableChallengesFromApi(string $cpf): array
84
    {
85 1
        $response = $this->client->get("cpf/{$cpf}/challenges");
86 1
        $statusCode = $response->getStatusCode();
87 1
        $body = (string)$response->getBody();
88 1
        if ($statusCode === 200) {
89 1
            return $this->parseChallengesList($body);
90
        }
91
92
        if ($statusCode === 403) {
93
            $response = json_decode($body);
94
            if ($response['error'] === CpfNotSubscribedToNfgException::ERROR_CODE) {
95
                throw new CpfNotSubscribedToNfgException($cpf, $response['message'] ?? null);
0 ignored issues
show
Bug introduced by
It seems like $response['message'] ?? null can also be of type null; however, parameter $message of PROCERGS\LoginCidadao\Cp...xception::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

95
                throw new CpfNotSubscribedToNfgException($cpf, /** @scrutinizer ignore-type */ $response['message'] ?? null);
Loading history...
96
            }
97
        }
98
99
        if ($statusCode === 429) {
100
            throw new TooManyRequestsHttpException();
101
        }
102
103
        throw new \LogicException("Invalid response code {$statusCode} with body {$body}");
104
    }
105
106 1
    private function selectChallengeFromApi(ChallengeInterface $challenge): ChallengeInterface
107
    {
108 1
        $response = $this->client->get("cpf/{$challenge->getCpf()}/challenges/{$challenge->getName()}");
109 1
        $statusCode = $response->getStatusCode();
110 1
        $body = (string)$response->getBody();
111
112 1
        if ($statusCode === 200) {
113 1
            return ChallengeParser::parseJson((string)$response->getBody());
114
        }
115
116
        if ($statusCode === 403) {
117
            $response = json_decode($body);
118
            if ($response['error'] === CpfNotSubscribedToNfgException::ERROR_CODE) {
119
                throw new CpfNotSubscribedToNfgException($challenge->getCpf(), $response['message'] ?? null);
0 ignored issues
show
Bug introduced by
It seems like $response['message'] ?? null can also be of type null; however, parameter $message of PROCERGS\LoginCidadao\Cp...xception::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

119
                throw new CpfNotSubscribedToNfgException($challenge->getCpf(), /** @scrutinizer ignore-type */ $response['message'] ?? null);
Loading history...
120
            }
121
        }
122
123
        if ($statusCode === 429) {
124
            throw new TooManyRequestsHttpException();
125
        }
126
127
        throw new \LogicException("Invalid response code {$statusCode} with body {$body}");
128
    }
129
130
    /**
131
     * @param string $json
132
     * @return ChallengeInterface[]
133
     */
134 1
    private function parseChallengesList(string $json): array
135
    {
136 1
        $response = json_decode($json, true);
137 1
        $challenges = [];
138 1
        if (array_key_exists('challenges', $response)) {
139 1
            $cpf = $response['cpf'];
140 1
            foreach ($response['challenges'] as $challenge) {
141 1
                $challenges[] = ChallengeParser::parseArray($challenge, $cpf);
142
            }
143
        }
144
145 1
        return $challenges;
146
    }
147
}
148