Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

discover fields #32

Merged
merged 11 commits into from
Oct 29, 2024
Merged
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
cbff26c91848f511b37214d9bc11a93c16ecb090
76cee3cc71ad94ce68d2213ab95305b1884d0aee
59e1dc2093e44dddf6a24ca536bff3680cfe8b1f
6fd284cacc2a88fc94e5a0accee7c790abef9b99
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ parameters:
- identifier: missingType.iterableValue
- identifier: missingType.generics
- '#PHPDoc tag .+ #'
- '#Unsafe usage of new static\(\)#'
cognitive_complexity:
class: 50
function: 10
42 changes: 42 additions & 0 deletions src/Services/Jira/Common/InteractsWithAtlassian.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/*
* Copyright (c) 2024. Encore Digital Group.
* All Right Reserved.
*/

namespace EncoreDigitalGroup\Atlassian\Services\Jira\Common;

use EncoreDigitalGroup\Atlassian\AtlassianHelper;
use EncoreDigitalGroup\Atlassian\Helpers\AuthHelper;
use Illuminate\Http\Client\PendingRequest;
use PHPGenesis\Http\HttpClient;
use PHPGenesis\Http\HttpClientBuilder;

trait InteractsWithAtlassian
{
public function __construct(public string $hostname, public string $username, public string $token)
{
$this->hostname = $hostname ?: AtlassianHelper::getHostname();
$this->username = $username ?: AtlassianHelper::getUsername();
$this->token = $token ?: AtlassianHelper::getToken();

$builder = new HttpClientBuilder();
}

public static function make(?string $hostname = null, ?string $username = null, ?string $token = null): static
{
return new static(
$hostname ?: AtlassianHelper::getHostname(),
$username ?: AtlassianHelper::getUsername(),
$token ?: AtlassianHelper::getToken()
);
}

public function client(): PendingRequest
{
AuthHelper::validate($this);

return HttpClient::withBasicAuth($this->username, $this->token);
}
}
38 changes: 38 additions & 0 deletions src/Services/Jira/JiraField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* Copyright (c) 2024. Encore Digital Group.
* All Right Reserved.
*/

namespace EncoreDigitalGroup\Atlassian\Services\Jira;

use EncoreDigitalGroup\Atlassian\Services\Jira\Common\InteractsWithAtlassian;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Fields\Field;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Fields\Traits\MapFields;
use Illuminate\Support\Collection;

class JiraField
{
use InteractsWithAtlassian;
use MapFields;

public const string FIELD_ENDPOINT = '/rest/api/2/field';

/** @returns Collection<Field> */
public function getAllFields(): Collection
{
$fields = $this->client()->get($this->hostname . self::FIELD_ENDPOINT);

$fields = json_decode($fields->body());

$fieldCollection = new Collection();

foreach ($fields as $field) {
$mappedField = $this->mapFields($field);
$fieldCollection->push($mappedField);
}

return $fieldCollection;
}
}
34 changes: 4 additions & 30 deletions src/Services/Jira/JiraProject.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@

namespace EncoreDigitalGroup\Atlassian\Services\Jira;

use EncoreDigitalGroup\Atlassian\AtlassianHelper;
use EncoreDigitalGroup\Atlassian\Helpers\AuthHelper;
use EncoreDigitalGroup\Atlassian\Services\Jira\Common\InteractsWithAtlassian;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Issues\Issue;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Issues\Traits\MapIssues;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\JQL\JqlResult;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\JQL\Traits\HandleJql;
use PHPGenesis\Http\HttpClient;
use PHPGenesis\Http\HttpClientBuilder;

/**
* @experimental
Expand All @@ -24,45 +21,25 @@
class JiraProject
{
use HandleJql;
use InteractsWithAtlassian;
use MapIssues;

public const string ISSUE_ENDPOINT = '/rest/api/2/issue';

public function __construct(public string $hostname, public string $username, public string $token)
{
$this->hostname = $hostname ?: AtlassianHelper::getHostname();
$this->username = $username ?: AtlassianHelper::getUsername();
$this->token = $token ?: AtlassianHelper::getToken();

$builder = new HttpClientBuilder();
}

public static function make(?string $hostname = null, ?string $username = null, ?string $token = null): JiraProject
{
return new self(
$hostname ?: AtlassianHelper::getHostname(),
$username ?: AtlassianHelper::getUsername(),
$token ?: AtlassianHelper::getToken()
);
}

public function getIssues(string $projectKey, int $startAt = 0, int $maxResults = 50): JqlResult
{
return $this->jql("project={$projectKey}", $startAt, $maxResults);
}

public function createIssue(Issue $issue): Issue
{
AuthHelper::validate($this);

/** @var string $issueJson */
$issueJson = json_encode($issue);

/** @var array $issueArray */
$issueArray = json_decode($issueJson, true);

$response = HttpClient::withBasicAuth($this->username, $this->token)
->post($this->hostname . self::ISSUE_ENDPOINT, $issueArray);
$response = $this->client()->post($this->hostname . self::ISSUE_ENDPOINT, $issueArray);

$response = json_decode($response->body());

Expand All @@ -72,10 +49,7 @@ public function createIssue(Issue $issue): Issue

public function getIssue(string $id): Issue
{
AuthHelper::validate($this);

$response = HttpClient::withBasicAuth($this->username, $this->token)
->get($this->hostname . self::ISSUE_ENDPOINT . '/' . $id);
$response = $this->client()->get($this->hostname . self::ISSUE_ENDPOINT . '/' . $id);

$response = json_decode($response->body());

Expand Down
19 changes: 19 additions & 0 deletions src/Services/Jira/Objects/Fields/Field.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* Copyright (c) 2024. Encore Digital Group.
* All Right Reserved.
*/

namespace EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Fields;

class Field
{
public ?string $id = null;
public ?string $key = null;
public ?string $name = null;
public bool $custom = false;
public bool $orderable = false;
public bool $navigable = false;
public bool $searchable = false;
}
27 changes: 27 additions & 0 deletions src/Services/Jira/Objects/Fields/Traits/MapFields.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/*
* Copyright (c) 2024. Encore Digital Group.
* All Right Reserved.
*/

namespace EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Fields\Traits;

use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\Fields\Field;

trait MapFields
{
private function mapFields(mixed $data): Field
{
$field = new Field();
$field->id = $data->id;
$field->key = $data->key;
$field->name = $data->name;
$field->custom = $data->custom;
$field->orderable = $data->orderable;
$field->navigable = $data->navigable;
$field->searchable = $data->searchable;

return $field;
}
}
18 changes: 8 additions & 10 deletions src/Services/Jira/Objects/JQL/Traits/HandleJql.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,22 @@

namespace EncoreDigitalGroup\Atlassian\Services\Jira\Objects\JQL\Traits;

use EncoreDigitalGroup\Atlassian\Helpers\AuthHelper;
use EncoreDigitalGroup\Atlassian\Services\Jira\Common\InteractsWithAtlassian;
use EncoreDigitalGroup\Atlassian\Services\Jira\Objects\JQL\JqlResult;
use PHPGenesis\Http\HttpClient;

trait HandleJql
{
use InteractsWithAtlassian;

public const string ISSUE_SEARCH_ENDPOINT = '/rest/api/2/search';

public function jql(string $query, int $startAt = 0, int $maxResults = 50): JqlResult
{
AuthHelper::validate($this);

$response = HttpClient::withBasicAuth($this->username, $this->token)
->get($this->hostname . self::ISSUE_SEARCH_ENDPOINT, [
'jql' => $query,
'startAt' => $startAt,
'maxResults' => $maxResults,
]);
$response = $this->client()->get($this->hostname . self::ISSUE_SEARCH_ENDPOINT, [
'jql' => $query,
'startAt' => $startAt,
'maxResults' => $maxResults,
]);

$response = json_decode($response->body());

Expand Down
100 changes: 67 additions & 33 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace EncoreDigitalGroup\Atlassian\Tests;

use EncoreDigitalGroup\Atlassian\Providers\AtlassianServiceProvider;
use EncoreDigitalGroup\Atlassian\Services\Jira\JiraField;
use EncoreDigitalGroup\Atlassian\Services\Jira\JiraProject;
use Illuminate\Foundation\Application;
use Illuminate\Http\Client\Factory as HttpFactory;
use Illuminate\Support\Facades\Facade;
Expand All @@ -11,12 +13,8 @@

class TestCase extends OrchestraTestCase
{
/**
* Get package providers.
*
* @param Application $app
* @return array
*/
protected const string HOSTNAME = 'https://example.atlassian.net';

protected function getPackageProviders($app): array
{
return [
Expand All @@ -34,11 +32,72 @@ protected function getEnvironmentSetUp($app): void
Facade::setFacadeApplication($app);

// Set up environment variables or configuration specific to your package
$app['config']->set('atlassian.hostname', 'https://example.atlassian.net');
$app['config']->set('atlassian.hostname', self::HOSTNAME);
$app['config']->set('atlassian.username', 'expectedUsername');
$app['config']->set('atlassian.token', 'expectedToken');

$fakeIssue = [
$this->setupSearchIssues();
$this->setupGetIssue();
$this->setupCreateIssue();
$this->setupGetAllFields();
}

private function setupSearchIssues(): void
{
// Search Fake Issues
HttpClient::fake([
self::HOSTNAME . JiraProject::ISSUE_SEARCH_ENDPOINT . '*' => HttpClient::response([
"expand" => "schema,names",
"startAt" => 0,
"maxResults" => 50,
"total" => 2,
"issues" => [$this->getFakeIssue()],
]),
]);
}

private function setupGetIssue(): void
{
// Get Fake Issue
HttpClient::fake([
self::HOSTNAME . JiraProject::ISSUE_ENDPOINT . '/10001' => HttpClient::response($this->getFakeIssue()),
]);
}

private function setupCreateIssue(): void
{
HttpClient::fake([
self::HOSTNAME . JiraProject::ISSUE_ENDPOINT => HttpClient::response([
'id' => '10001',
'key' => 'TEST-1',
'self' => 'https://example.atlassian.net/rest/api/issue/10001',
]),
]);
}

private function setupGetAllFields(): void
{
HttpClient::fake([
self::HOSTNAME . JiraField::FIELD_ENDPOINT => HttpClient::response([$this->getFakeFields()]),
]);
}

private function getFakeFields(): array
{
return [
'id' => '10000',
'key' => '10000',
'name' => 'customfield_10000',
'custom' => true,
'orderable' => true,
'navigable' => true,
'searchable' => true,
];
}

private function getFakeIssue(): array
{
return [
"expand" => "",
"id" => "10001",
"self" => "https://example.atlassian.net/rest/api/2/issue/10001",
Expand Down Expand Up @@ -79,30 +138,5 @@ protected function getEnvironmentSetUp($app): void
],
],
];

// Search Fake Issues
HttpClient::fake([
'https://example.atlassian.net/rest/api/2/search*' => HttpClient::response([
"expand" => "schema,names",
"startAt" => 0,
"maxResults" => 50,
"total" => 2,
"issues" => [$fakeIssue],
]),
]);

// Get Fake Issue
HttpClient::fake([
'https://example.atlassian.net/rest/api/2/issue/10001' => HttpClient::response($fakeIssue),
]);

// Create Fake Issue
HttpClient::fake([
'https://example.atlassian.net/rest/api/2/issue' => HttpClient::response([
'id' => '10001',
'key' => 'TEST-1',
'self' => 'https://example.atlassian.net/rest/api/issue/10001',
]),
]);
}
}
Loading