diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..94fed74 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,22 @@ +name: Tests + +on: + push: + pull_request: + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ['7.1', '8.5'] + + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + - run: composer update --prefer-dist --no-interaction + - run: vendor/bin/phpunit diff --git a/README.md b/README.md index a27b422..38b261a 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,12 @@ # PHP GitHub Status API -[](https://travis-ci.com/Jord-JD/php-github-status-api) - ---- - -⚠️ **Warning:** As of 11th December 2018, GitHub have deprecated the status page that this package parses, so current status information may not be up-to-date. More information: https://blog.github.com/2018-12-11-introducing-the-new-github-status-site/ - ---- +[](https://github.com/Jord-JD/php-github-status-api/actions/workflows/tests.yml) This package provides a way to programmatically determine if GitHub is working -well, or experiencing issues. -Both the current status and historical statuses can be looked up by date. +well, or experiencing issues. It uses GitHub's current Statuspage API. + +The replacement API does not provide the historical feed used by older package +versions. Passing a past date therefore returns `GitHubStatus::UNKNOWN`.
diff --git a/composer.json b/composer.json
index 2a05d53..d956f2c 100644
--- a/composer.json
+++ b/composer.json
@@ -10,12 +10,11 @@
],
"license": "LGPL-3.0-only",
"require": {
- "ivopetkov/html5-dom-document-php": "^1.1",
"nesbot/carbon": "^2.7",
"php": "^7.1 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^9.6"
+ "phpunit/phpunit": "^7.5 || ^9.6"
},
"autoload": {
"psr-4": {
diff --git a/src/Client.php b/src/Client.php
index 7236325..234ec15 100644
--- a/src/Client.php
+++ b/src/Client.php
@@ -4,60 +4,49 @@
use Carbon\Carbon;
use JordJD\GitHubStatusApi\Enums\GitHubStatus;
-use IvoPetkov\HTML5DOMDocument;
class Client
{
- const GITHUB_STATUS_URL = 'https://status.github.com/messages';
+ const GITHUB_STATUS_URL = 'https://www.githubstatus.com/api/v2/status.json';
- const CLASS_TO_STATUS_MAP = [
- 'good' => GitHubStatus::GOOD,
- 'major' => GitHubStatus::MAJOR,
+ const INDICATOR_TO_STATUS_MAP = [
+ 'none' => GitHubStatus::GOOD,
'minor' => GitHubStatus::MINOR,
+ 'major' => GitHubStatus::MAJOR,
+ 'critical' => GitHubStatus::MAJOR,
];
+ private $statusFetcher;
+
+ public function __construct(callable $statusFetcher = null)
+ {
+ $this->statusFetcher = $statusFetcher;
+ }
+
public function status(Carbon $datetime = null)
{
- if ($datetime === null) {
- $datetime = Carbon::now();
+ if ($datetime !== null && !$datetime->isToday()) {
+ return GitHubStatus::UNKNOWN;
}
- $dom = $this->getDomDocument($datetime);
-
- $timeElements = $dom->querySelectorAll('time');
-
- /** @var HTML5DOMDocument $timeElement*/
- foreach($timeElements as $timeElement) {
-
- $timeElementDatetime = Carbon::parse($timeElement->getAttribute('datetime'));
+ $response = $this->statusFetcher
+ ? call_user_func($this->statusFetcher)
+ : @file_get_contents(self::GITHUB_STATUS_URL);
- if ($datetime >= $timeElementDatetime) {
-
- $class = $timeElement->parentNode->attributes->getNamedItem('class')->textContent;
- $classParts = explode(' ', $class);
-
- foreach($classParts as $classPart) {
-
- if (array_key_exists($classPart, self::CLASS_TO_STATUS_MAP)) {
- return self::CLASS_TO_STATUS_MAP[$classPart];
- }
-
- }
+ if (!is_string($response)) {
+ return GitHubStatus::UNKNOWN;
+ }
- return GitHubStatus::UNKNOWN;
- }
+ $statusResponse = json_decode($response, true);
+ if (!is_array($statusResponse) || empty($statusResponse['status']['indicator'])) {
+ return GitHubStatus::UNKNOWN;
}
- }
-
- private function getDomDocument(Carbon $datetime)
- {
- $url = self::GITHUB_STATUS_URL.'/'.$datetime->format('Y-m-d');
- $html = file_get_contents($url);
- $dom = new HTML5DOMDocument();
- $dom->loadHTML($html);
+ $indicator = $statusResponse['status']['indicator'];
- return $dom;
+ return array_key_exists($indicator, self::INDICATOR_TO_STATUS_MAP)
+ ? self::INDICATOR_TO_STATUS_MAP[$indicator]
+ : GitHubStatus::UNKNOWN;
}
-}
\ No newline at end of file
+}
diff --git a/tests/ClientTest.php b/tests/ClientTest.php
index 79f4f86..9726b3b 100644
--- a/tests/ClientTest.php
+++ b/tests/ClientTest.php
@@ -2,45 +2,50 @@
namespace JordJD\GitHubStatusApi;
-use JordJD\GitHubStatusApi\Client;
+use Carbon\Carbon;
use JordJD\GitHubStatusApi\Enums\GitHubStatus;
use PHPUnit\Framework\TestCase;
class ClientTest extends TestCase
{
- public function testStatusShouldReturnGood()
+ /**
+ * @dataProvider statusIndicatorProvider
+ */
+ public function testStatusIndicatorsAreMapped($indicator, $expectedStatus)
{
- $mockedClient = $this->createMock(Client::class);
- $mockedClient->method('status')
- ->willReturn(GitHubStatus::GOOD);
+ $client = new Client(function () use ($indicator) {
+ return json_encode(['status' => ['indicator' => $indicator]]);
+ });
- $this->assertSame(GitHubStatus::GOOD, $mockedClient->status());
+ $this->assertSame($expectedStatus, $client->status());
}
- public function testStatusShouldReturnMinor()
+ public function statusIndicatorProvider()
{
- $mockedClient = $this->createMock(Client::class);
- $mockedClient->method('status')
- ->willReturn(GitHubStatus::MINOR);
-
- $this->assertSame(GitHubStatus::MINOR, $mockedClient->status());
+ return [
+ ['none', GitHubStatus::GOOD],
+ ['minor', GitHubStatus::MINOR],
+ ['major', GitHubStatus::MAJOR],
+ ['critical', GitHubStatus::MAJOR],
+ ['unrecognised', GitHubStatus::UNKNOWN],
+ ];
}
- public function testStatusShouldReturnMajor()
+ public function testInvalidResponsesReturnUnknown()
{
- $mockedClient = $this->createMock(Client::class);
- $mockedClient->method('status')
- ->willReturn(GitHubStatus::MAJOR);
+ $client = new Client(function () {
+ return 'not-json';
+ });
- $this->assertSame(GitHubStatus::MAJOR, $mockedClient->status());
+ $this->assertSame(GitHubStatus::UNKNOWN, $client->status());
}
- public function testStatusShouldReturnUnknown()
+ public function testHistoricalDatesReturnUnknown()
{
- $mockedClient = $this->createMock(Client::class);
- $mockedClient->method('status')
- ->willReturn(GitHubStatus::UNKNOWN);
+ $client = new Client(function () {
+ return json_encode(['status' => ['indicator' => 'none']]);
+ });
- $this->assertSame(GitHubStatus::UNKNOWN, $mockedClient->status());
+ $this->assertSame(GitHubStatus::UNKNOWN, $client->status(Carbon::parse('2018-12-06 17:00')));
}
}