• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tylernathanreed / jira-client-php / 13954592091

19 Mar 2025 06:57PM UTC coverage: 72.323%. First build
13954592091

push

github

tylernathanreed
+ Added unique exceptions

0 of 10 new or added lines in 5 files covered. (0.0%)

4965 of 6865 relevant lines covered (72.32%)

9.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.67
/src/Factory.php
1
<?php
2

3
namespace Jira\Client;
4

5
use Closure;
6
use GuzzleHttp\Client as Guzzle;
7
use GuzzleHttp\HandlerStack;
8
use GuzzleHttp\Promise\PromiseInterface;
9
use GuzzleHttp\RequestOptions;
10
use GuzzleHttp\UriTemplate\UriTemplate;
11
use Jira\Client\Contracts\Factory as FactoryContract;
12
use Jira\Client\Exceptions\StrayRequestException;
13
use Psr\Http\Message\RequestInterface;
14
use Psr\Http\Message\ResponseInterface;
15

16
/**
17
 * @phpstan-type TOptions array{
18
 *    auth?: array{0:string,1:string},
19
 *    connect_timeout: int,
20
 *    crypto_method: int,
21
 *    debug: bool|resource,
22
 *    headers: array{
23
 *       Authorization?:string,
24
 *       'User-Agent'?:string,
25
 *    },
26
 *    http_errors: false,
27
 *    json?: array<int|string,mixed>,
28
 *    query?: array<string,mixed>,
29
 *    timeout: int,
30
 * }
31
 */
32
class Factory implements FactoryContract
33
{
34
    protected Guzzle $client;
35

36
    /** @var list<Closure(RequestInterface,array<string,mixed>):?PromiseInterface> */
37
    protected array $stubCallbacks = [];
38

39
    public function make(PendingOperation $operation, Configuration $config): ResponseInterface
477✔
40
    {
41
        return $this->newResponse($operation, $config);
477✔
42
    }
43

44
    /** @param Closure(RequestInterface,array<string,mixed>):?PromiseInterface $callback */
45
    public function fake(Closure $callback): static
477✔
46
    {
47
        $this->stubCallbacks[] = $callback;
477✔
48

49
        return $this;
477✔
50
    }
51

52
    protected function newResponse(PendingOperation $operation, Configuration $config): ResponseInterface
477✔
53
    {
54
        return $this->newClient()->request(
477✔
55
            method: $operation->method,
477✔
56
            uri: $this->getUrl($operation, $config),
477✔
57
            options: $this->getOptions($operation, $config),
477✔
58
        );
477✔
59
    }
60

61
    protected function getUrl(PendingOperation $operation, Configuration $config): string
477✔
62
    {
63
        $url = ltrim(rtrim($config->host, '/') . '/' . ltrim($operation->uri, '/'), '/');
477✔
64

65
        return UriTemplate::expand($url, $operation->path);
477✔
66
    }
67

68
    /** @return TOptions */
69
    protected function getOptions(PendingOperation $operation, Configuration $config): array
477✔
70
    {
71
        $options = [
477✔
72
            RequestOptions::CONNECT_TIMEOUT => 10,
477✔
73
            RequestOptions::CRYPTO_METHOD => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
477✔
74
            RequestOptions::DEBUG => $config->debug,
477✔
75
            RequestOptions::HEADERS => [
477✔
76
                'Accept' => 'application/json',
477✔
77
            ],
477✔
78
            RequestOptions::HTTP_ERRORS => false,
477✔
79
            RequestOptions::TIMEOUT => 30,
477✔
80
        ];
477✔
81

82
        if (! empty($config->accessToken)) {
477✔
83
            $options[RequestOptions::HEADERS]['Authorization'] = trim('Bearer ' . $config->accessToken);
×
84
        } elseif (! empty($config->username) && ! empty($config->password)) {
477✔
85
            $options[RequestOptions::AUTH] = [$config->username, $config->password];
477✔
86
        }
87

88
        if (! empty($config->userAgent)) {
477✔
89
            $options[RequestOptions::HEADERS]['User-Agent'] = trim($config->userAgent);
×
90
        }
91

92
        if (! empty($operation->query)) {
477✔
93
            $options[RequestOptions::QUERY] = $operation->query;
180✔
94
        }
95

96
        if (! empty($operation->body)) {
477✔
97
            $options[RequestOptions::JSON] = $operation->body instanceof Dto
165✔
98
                ? $operation->body->toArray()
165✔
99
                : $operation->body;
×
100
        }
101

102
        return $options;
477✔
103
    }
104

105
    protected function newClient(): Guzzle
477✔
106
    {
107
        return new Guzzle([
477✔
108
            'handler' => $this->buildHandlerStack(),
477✔
109
        ]);
477✔
110
    }
111

112
    protected function buildHandlerStack(): HandlerStack
477✔
113
    {
114
        $handler = HandlerStack::create();
477✔
115

116
        $handler->push($this->buildStubHandler());
477✔
117

118
        return $handler;
477✔
119
    }
120

121
    protected function buildStubHandler(): Closure
477✔
122
    {
123
        return function (Closure $handler): Closure {
477✔
124
            /** @var Closure(RequestInterface, array<string,mixed>):?PromiseInterface $handler */
125

126
            return function (RequestInterface $request, array $options) use ($handler): ?PromiseInterface {
477✔
127
                /** @var array<string,mixed> $options */
128

129
                if (empty($this->stubCallbacks)) {
477✔
130
                    return $handler($request, $options);
×
131
                }
132

133
                foreach ($this->stubCallbacks as $callback) {
477✔
134
                    if (! is_null($response = $callback($request, $options))) {
477✔
135
                        return $response;
477✔
136
                    }
137
                }
138

NEW
139
                throw new StrayRequestException(sprintf(
×
140
                    'Attempted request to [%s] without a matching fake.',
×
141
                    (string) $request->getUri()
×
142
                ));
×
143
            };
477✔
144
        };
477✔
145
    }
146
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc