Skip to content

Commit f87d0c1

Browse files
committed
Add CheckResult enum with warning state support and helper methods
1 parent 44b1667 commit f87d0c1

File tree

10 files changed

+220
-2
lines changed

10 files changed

+220
-2
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to `ohdear-php-sdk` will be documented in this file
44

5+
## Add warning state support - 2026-02-28
6+
7+
### What changed
8+
9+
- Added `CheckResult` backed string enum (`pending`, `succeeded`, `warning`, `failed`, `errored-or-timed-out`) with helper methods (`isUp()`, `isDown()`, `isPending()`, `isWarning()`)
10+
- Added `checkResult()` method to `Check`, `Monitor`, and `CheckSummary` DTOs that returns the typed enum
11+
512
## Add missing API endpoints - 2026-02-17
613

714
### What changed

README.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,51 @@ $checkSummary = $ohDear->checkSummary($monitorId, CheckType::CertificateHealth);
152152

153153
echo "Check result: {$checkSummary->result}\n";
154154
echo "Summary: {$checkSummary->summary}\n";
155+
156+
// Use the checkResult() method to get the typed enum with helper methods
157+
if ($checkSummary->checkResult()->isUp()) {
158+
echo "Monitor is reachable\n";
159+
}
160+
161+
if ($checkSummary->checkResult()->isWarning()) {
162+
echo "Partial connectivity issue detected\n";
163+
}
164+
165+
if ($checkSummary->checkResult()->isDown()) {
166+
echo "Monitor is down\n";
167+
}
155168
```
156169

157-
You can request a summary for all available cases in the `CheckType` enum.`
170+
You can request a summary for all available cases in the `CheckType` enum.
171+
172+
#### Check result enum
173+
174+
The `CheckResult` enum represents the possible states of a check. Access it via the `checkResult()` method available on `Check`, `Monitor`, and `CheckSummary` DTOs:
175+
176+
```php
177+
use OhDear\PhpSdk\Enums\CheckResult;
178+
179+
$checkSummary = $ohDear->checkSummary($monitorId, CheckType::Uptime);
180+
181+
// The raw string is still available
182+
echo $checkSummary->result; // 'succeeded', 'warning', 'failed', etc.
183+
184+
// Use checkResult() for the typed enum
185+
$result = $checkSummary->checkResult();
186+
187+
// Available cases:
188+
CheckResult::Pending; // 'pending'
189+
CheckResult::Succeeded; // 'succeeded'
190+
CheckResult::Warning; // 'warning' — primary location reports down, secondary confirms reachable
191+
CheckResult::Failed; // 'failed'
192+
CheckResult::ErroredOrTimedOut; // 'errored-or-timed-out'
193+
194+
// Helper methods:
195+
$result->isUp(); // true for Succeeded and Warning
196+
$result->isDown(); // true for Failed and ErroredOrTimedOut
197+
$result->isPending(); // true for Pending only
198+
$result->isWarning(); // true for Warning only
199+
```
158200

159201
#### Getting certificate health for a monitor
160202

src/Dto/Check.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace OhDear\PhpSdk\Dto;
44

5+
use OhDear\PhpSdk\Enums\CheckResult;
6+
57
class Check
68
{
79
public function __construct(
@@ -17,6 +19,15 @@ public function __construct(
1719
public ?array $activeSnooze,
1820
) {}
1921

22+
public function checkResult(): ?CheckResult
23+
{
24+
if ($this->latestRunResult === null) {
25+
return null;
26+
}
27+
28+
return CheckResult::tryFrom($this->latestRunResult);
29+
}
30+
2031
public static function fromResponse(array $data): self
2132
{
2233
return new self(

src/Dto/CheckSummary.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,25 @@
22

33
namespace OhDear\PhpSdk\Dto;
44

5+
use OhDear\PhpSdk\Enums\CheckResult;
6+
57
class CheckSummary
68
{
79
public function __construct(
810
public string $result,
911
public ?string $summary,
1012
) {}
1113

14+
public function checkResult(): ?CheckResult
15+
{
16+
return CheckResult::tryFrom($this->result);
17+
}
18+
1219
public static function fromResponse(array $data): self
1320
{
1421
return new self(
1522
result: $data['result'],
16-
summary: $data['summary'],
23+
summary: $data['summary'] ?? null,
1724
);
1825
}
1926
}

src/Dto/Monitor.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace OhDear\PhpSdk\Dto;
44

5+
use OhDear\PhpSdk\Enums\CheckResult;
6+
57
class Monitor
68
{
79
public function __construct(
@@ -40,6 +42,15 @@ public function __construct(
4042
public ?string $updatedAt = null,
4143
) {}
4244

45+
public function checkResult(): ?CheckResult
46+
{
47+
if ($this->summarizedCheckResult === null) {
48+
return null;
49+
}
50+
51+
return CheckResult::tryFrom($this->summarizedCheckResult);
52+
}
53+
4354
public static function fromResponse(array $data): self
4455
{
4556
return new self(

src/Enums/CheckResult.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace OhDear\PhpSdk\Enums;
4+
5+
enum CheckResult: string
6+
{
7+
case Pending = 'pending';
8+
case Succeeded = 'succeeded';
9+
case Warning = 'warning';
10+
case Failed = 'failed';
11+
case ErroredOrTimedOut = 'errored-or-timed-out';
12+
13+
public function isUp(): bool
14+
{
15+
return match ($this) {
16+
self::Succeeded, self::Warning => true,
17+
default => false,
18+
};
19+
}
20+
21+
public function isDown(): bool
22+
{
23+
return match ($this) {
24+
self::Failed, self::ErroredOrTimedOut => true,
25+
default => false,
26+
};
27+
}
28+
29+
public function isPending(): bool
30+
{
31+
return $this === self::Pending;
32+
}
33+
34+
public function isWarning(): bool
35+
{
36+
return $this === self::Warning;
37+
}
38+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"statusCode": 200,
3+
"headers": {
4+
"Date": "Sun, 10 Aug 2025 18:46:17 GMT",
5+
"Content-Type": "application\/json",
6+
"Transfer-Encoding": "chunked",
7+
"Connection": "keep-alive",
8+
"Server": "cloudflare",
9+
"Vary": "Accept-Encoding",
10+
"Cache-Control": "no-cache, private",
11+
"X-Ratelimit-Limit": "500",
12+
"X-Ratelimit-Remaining": "498",
13+
"Access-Control-Allow-Origin": "*",
14+
"X-Frame-Options": "SAMEORIGIN",
15+
"X-Xss-Protection": "1; mode=block",
16+
"X-Content-Type-Options": "nosniff",
17+
"Cf-Cache-Status": "BYPASS"
18+
},
19+
"data": "{\"result\":\"warning\",\"summary\":\"Primary location reports down, secondary confirms reachable.\"}",
20+
"context": []
21+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
use OhDear\PhpSdk\Enums\CheckResult;
4+
5+
it('has all expected cases', function () {
6+
expect(CheckResult::cases())->toHaveCount(5);
7+
expect(CheckResult::Pending->value)->toBe('pending');
8+
expect(CheckResult::Succeeded->value)->toBe('succeeded');
9+
expect(CheckResult::Warning->value)->toBe('warning');
10+
expect(CheckResult::Failed->value)->toBe('failed');
11+
expect(CheckResult::ErroredOrTimedOut->value)->toBe('errored-or-timed-out');
12+
});
13+
14+
it('can be created from string values', function () {
15+
expect(CheckResult::from('succeeded'))->toBe(CheckResult::Succeeded);
16+
expect(CheckResult::from('warning'))->toBe(CheckResult::Warning);
17+
expect(CheckResult::from('failed'))->toBe(CheckResult::Failed);
18+
expect(CheckResult::from('pending'))->toBe(CheckResult::Pending);
19+
expect(CheckResult::from('errored-or-timed-out'))->toBe(CheckResult::ErroredOrTimedOut);
20+
});
21+
22+
it('returns null for unknown values with tryFrom', function () {
23+
expect(CheckResult::tryFrom('unknown'))->toBeNull();
24+
expect(CheckResult::tryFrom(''))->toBeNull();
25+
});
26+
27+
it('correctly identifies up states', function () {
28+
expect(CheckResult::Succeeded->isUp())->toBeTrue();
29+
expect(CheckResult::Warning->isUp())->toBeTrue();
30+
expect(CheckResult::Pending->isUp())->toBeFalse();
31+
expect(CheckResult::Failed->isUp())->toBeFalse();
32+
expect(CheckResult::ErroredOrTimedOut->isUp())->toBeFalse();
33+
});
34+
35+
it('correctly identifies down states', function () {
36+
expect(CheckResult::Failed->isDown())->toBeTrue();
37+
expect(CheckResult::ErroredOrTimedOut->isDown())->toBeTrue();
38+
expect(CheckResult::Succeeded->isDown())->toBeFalse();
39+
expect(CheckResult::Warning->isDown())->toBeFalse();
40+
expect(CheckResult::Pending->isDown())->toBeFalse();
41+
});
42+
43+
it('correctly identifies pending state', function () {
44+
expect(CheckResult::Pending->isPending())->toBeTrue();
45+
expect(CheckResult::Succeeded->isPending())->toBeFalse();
46+
expect(CheckResult::Warning->isPending())->toBeFalse();
47+
expect(CheckResult::Failed->isPending())->toBeFalse();
48+
expect(CheckResult::ErroredOrTimedOut->isPending())->toBeFalse();
49+
});
50+
51+
it('correctly identifies warning state', function () {
52+
expect(CheckResult::Warning->isWarning())->toBeTrue();
53+
expect(CheckResult::Succeeded->isWarning())->toBeFalse();
54+
expect(CheckResult::Failed->isWarning())->toBeFalse();
55+
expect(CheckResult::Pending->isWarning())->toBeFalse();
56+
expect(CheckResult::ErroredOrTimedOut->isWarning())->toBeFalse();
57+
});

tests/OhDearTests/ChecksTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use OhDear\PhpSdk\Enums\CheckResult;
34
use OhDear\PhpSdk\Requests\Checks\DisableCheckRequest;
45
use OhDear\PhpSdk\Requests\Checks\EnableCheckRequest;
56
use OhDear\PhpSdk\Requests\Checks\RequestCheckRunRequest;
@@ -21,6 +22,8 @@
2122

2223
expect($check->id)->toBe(940704);
2324
expect($check->enabled)->toBe(true);
25+
expect($check->latestRunResult)->toBe('succeeded');
26+
expect($check->checkResult())->toBe(CheckResult::Succeeded);
2427
});
2528

2629
it('can disable a check', function () {

tests/OhDearTests/MonitorsTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use OhDear\PhpSdk\Enums\CheckResult;
34
use OhDear\PhpSdk\Enums\CheckType;
45
use OhDear\PhpSdk\Requests\Monitors\AddToBrokenLinksWhitelistRequest;
56
use OhDear\PhpSdk\Requests\Monitors\CreateMonitorRequest;
@@ -36,6 +37,8 @@
3637
$monitor = $this->ohDear->monitor(82063);
3738

3839
expect($monitor->url)->toBe('https://laravel.com');
40+
expect($monitor->summarizedCheckResult)->toBe('succeeded');
41+
expect($monitor->checkResult())->toBe(CheckResult::Succeeded);
3942
});
4043

4144
it('can create a monitor', function () {
@@ -74,6 +77,24 @@
7477
$checkSummary = $this->ohDear->checkSummary(82060, CheckType::CertificateHealth);
7578

7679
expect($checkSummary->result)->toBe('succeeded');
80+
expect($checkSummary->checkResult())->toBe(CheckResult::Succeeded);
81+
expect($checkSummary->checkResult()->isUp())->toBeTrue();
82+
expect($checkSummary->checkResult()->isDown())->toBeFalse();
83+
expect($checkSummary->checkResult()->isWarning())->toBeFalse();
84+
});
85+
86+
it('can get a warning check summary for a monitor', function () {
87+
MockClient::global([
88+
GetCheckSummaryRequest::class => MockResponse::fixture('check-summary-warning'),
89+
]);
90+
91+
$checkSummary = $this->ohDear->checkSummary(82060, CheckType::Uptime);
92+
93+
expect($checkSummary->result)->toBe('warning');
94+
expect($checkSummary->checkResult())->toBe(CheckResult::Warning);
95+
expect($checkSummary->checkResult()->isUp())->toBeTrue();
96+
expect($checkSummary->checkResult()->isDown())->toBeFalse();
97+
expect($checkSummary->checkResult()->isWarning())->toBeTrue();
7798
});
7899

79100
it('can get notification destinations for a monitor', function () {

0 commit comments

Comments
 (0)