Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
JiraClient
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
8 / 8
17
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
4
 http
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 sendRequest
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 post
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 put
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handleResponse
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
3
 issues
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Javidnikoo\LaravelAtlassian\Jira\Clients;
4
5use Illuminate\Http\Client\PendingRequest;
6use Illuminate\Http\Client\RequestException;
7use Illuminate\Http\Client\Response;
8use Javidnikoo\LaravelAtlassian\Atlassian\Http\AtlassianHttpFactory;
9use Javidnikoo\LaravelAtlassian\Jira\Contracts\JiraClientInterface;
10use Javidnikoo\LaravelAtlassian\Jira\Exceptions\JiraException;
11use Javidnikoo\LaravelAtlassian\Jira\Features\Issue\Resource\IssueResource;
12use Symfony\Component\HttpFoundation\Request;
13
14class JiraClient implements JiraClientInterface
15{
16    protected array $config;
17
18    public function __construct(array $config)
19    {
20        $this->config = $config;
21
22        if (empty($this->config['base_url'])) {
23            throw new JiraException(
24                'Missing config: atlassian.jira.base_url. '
25                .'Did you forget to set ATLASSIAN_JIRA_BASE_URL in your .env?'
26            );
27        }
28
29        if (empty($this->config['email'])) {
30            throw new JiraException(
31                'Missing config: atlassian.jira.email. '
32                .'Did you forget to set ATLASSIAN_EMAIL in your .env?'
33            );
34        }
35
36        if (empty($this->config['api_token'])) {
37            throw new JiraException(
38                'Missing config: atlassian.jira.api_token. '
39                .'Did you forget to set ATLASSIAN_API_TOKEN in your .env?'
40            );
41        }
42    }
43
44    protected function http(): PendingRequest
45    {
46        return AtlassianHttpFactory::make($this->config);
47    }
48
49    private function sendRequest(string $method, string $endpoint, array $data = [], array $query = []): array
50    {
51        try {
52            $request = $this->http();
53
54            if ($method === Request::METHOD_GET) {
55                $response = $request->get($endpoint, $query);
56            } elseif ($method === Request::METHOD_POST) {
57                $response = $request->post($endpoint, $data);
58            } elseif ($method === Request::METHOD_PUT) {
59                $response = $request->put($endpoint, $data);
60            } else {
61                throw new \InvalidArgumentException('Unsupported HTTP method');
62            }
63        } catch (RequestException $e) {
64            $response = $e->response;
65        }
66
67        return $this->handleResponse($response, $endpoint, $method);
68    }
69
70    public function post(string $endpoint, array $data): array
71    {
72        return $this->sendRequest(Request::METHOD_POST, $endpoint, $data);
73    }
74
75    public function put(string $endpoint, array $data): array
76    {
77        return $this->sendRequest(Request::METHOD_PUT, $endpoint, $data);
78    }
79
80    public function get(string $endpoint, array $query = []): array
81    {
82        return $this->sendRequest(Request::METHOD_GET, $endpoint, [], $query);
83    }
84
85    private function handleResponse(Response $response, string $endpoint, string $method): array
86    {
87        if ($response->failed()) {
88            $status = $response->status();
89
90            $message = $response->json('errorMessages')[0]
91                ?? ($response->json('errors') ? implode(', ', $response->json('errors')) : null)
92                ?? $response->json('message')
93                ?? $response->body()
94                ?? 'Unknown Jira API error';
95
96            throw new JiraException(
97                message: $message,
98                code: $status,
99                context: [
100                    'service' => 'jira',
101                    'method' => $method,
102                    'url' => $response->effectiveUri()?->__toString() ?? $endpoint,
103                    'status' => $status,
104                    'body' => $response->json() ?? $response->body(),
105                ]
106            );
107        }
108
109        return $response->json() ?? [];
110    }
111
112    public function issues(): IssueResource
113    {
114        return new IssueResource($this);
115    }
116}