diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 39a77e7..467d9f1 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -5,20 +5,33 @@ on: paths: - '**.php' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: php-code-styling: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - - name: Checkout code - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: ref: ${{ github.head_ref }} + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.4 + coverage: none + + - name: Run composer install + run: composer install -n --prefer-dist + - name: Fix PHP code style issues - uses: aglipanci/laravel-pint-action@2.1.0 + run: composer format - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Fix styling diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index bad6db7..7178377 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: [8.4, 8.3, 8.2, 8.1] + php: [8.4, 8.3, 8.2] dependency-version: [prefer-lowest, prefer-stable] name: P${{ matrix.php }} - ${{ matrix.dependency-version }} - ${{ matrix.os }} diff --git a/.gitignore b/.gitignore index 6dd160e..5969f79 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,5 @@ build composer.lock docs vendor -tests/ApiTest.php -.phpunit.result.cache .env -.php_cs.cache -.php-cs-fixer.cache .phpunit.cache -tests/TestSupport/.env - diff --git a/README.md b/README.md index c9da6b9..85e3924 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ try { For all other errors, the SDK will throw an `\OhDear\PhpSdk\Exceptions\OhDearException`. -### Get user info +### [Get user info](https://ohdear.app/docs/api/user-info) ```php // returns OhDear\PhpSdk\Dto\User @@ -87,10 +87,12 @@ $user = $ohDear->me(); echo $user->email; // returns the email address of the authenticated user ``` -### Monitors +### [Monitors](https://ohdear.app/docs/api/monitors) Monitors are the core of Oh Dear - they watch your websites, APIs, and services for uptime, performance, SSL certificates, broken links, and more. You can create different types of monitors (HTTP, ping, TCP) and configure various checks for each one. +[View all monitor API documentation](https://ohdear.app/docs/api/monitors) + #### Get all monitors ```php @@ -104,37 +106,40 @@ foreach($monitors as $monitor) { #### Create a monitor -You can use the `createMonitor` method to create a monitor. - -```php +```php $monitor = $ohDear->createMonitor([ 'url' => 'https://example.com', 'type' => 'http', 'team_id' => 1, ]); - -echo $monitor->url; // returns https://example.com ``` -You can find a list of attributes you can pass to the `createMonitor` method in the [Oh Dear API documentation](#oh-dear-documentation). +See the [Oh Dear API documentation](#oh-dear-documentation) for all available attributes. #### Getting a single monitor -You can use the `monitor` method to get a single monitor. - ```php -// returns OhDear\PhpSdk\Dto\Monitor $monitor = $ohDear->monitor($monitorId); ``` #### Deleting a monitor -You can use the `deleteMonitor` method to delete a monitor. - ```php $ohDear->deleteMonitor($monitorId); ``` +#### Getting a monitor by URL + +```php +$monitor = $ohDear->monitorByUrl('https://example.com'); +``` + +#### Adding a URL to the broken links whitelist + +```php +$ohDear->addToBrokenLinksWhitelist($monitorId, 'https://example.com/skip'); +``` + #### Getting a check summary for a monitor You can get a summary of a specific check type for a monitor, which provides the current status and a human-readable summary: @@ -187,7 +192,7 @@ foreach ($certificateHealth->certificateChainIssuers as $issuer) { } ``` -### Status pages +### [Status pages](https://ohdear.app/docs/api/status-pages) Status pages provide a public way to communicate the status of your services to your users. They automatically reflect the health of your monitors and allow you to post updates during incidents or maintenance windows. @@ -211,15 +216,78 @@ You can use the `statusPage` method to get a single status page. $statusPage = $ohDear->statusPage($statusPageId); ``` +#### Creating a status page + +```php +$statusPage = $ohDear->createStatusPage([ + 'title' => 'My Status Page', + 'team_id' => 1, +]); +``` + #### Deleting a status page -You can use the `deleteStatusPage` method to delete a status page. +```php +$ohDear->deleteStatusPage($statusPageId); +``` + +#### Managing monitors on a status page + +```php +// Add monitors +$statusPage = $ohDear->addStatusPageMonitors($statusPageId, [ + 'monitors' => [82060], +]); + +// Remove a monitor +$ohDear->deleteStatusPageMonitor($statusPageId, $monitorId); +``` + +#### Status page updates + +```php +// List updates +$updates = $ohDear->statusPageUpdates($statusPageId); + +// Create an update +$update = $ohDear->createStatusPageUpdate([ + 'status_page_id' => $statusPageId, + 'title' => 'Our site is down', + 'text' => 'We are working on it!', + 'severity' => 'high', + 'time' => '2025-01-01 00:00:00', + 'pinned' => true, +]); + +// Update an existing update +$update = $ohDear->updateStatusPageUpdate($updateId, [ + 'title' => 'Issue resolved', +]); + +// Delete an update +$ohDear->deleteStatusPageUpdate($updateId); +``` + +#### Status page update templates ```php -$ohDear->deleteStatusPage($statusPageId) +$templates = $ohDear->statusPageUpdateTemplates(); + +$template = $ohDear->createStatusPageUpdateTemplate([ + 'name' => 'Maintenance', + 'title' => 'Scheduled maintenance', + 'text' => 'We are performing scheduled maintenance.', + 'severity' => 'info', +]); + +$template = $ohDear->updateStatusPageUpdateTemplate($templateId, [ + 'name' => 'Updated template', +]); + +$ohDear->deleteStatusPageUpdateTemplate($templateId); ``` -### Checks +### [Checks](https://ohdear.app/docs/api/checks) Checks are individual monitoring tasks that belong to monitors (like uptime, SSL certificate, performance, broken links, etc.). You can control each check independently - enabling, disabling, requesting immediate runs, and temporarily snoozing notifications. @@ -282,7 +350,7 @@ $check = $ohDear->unsnoozeCheck($checkId); echo $check->activeSnooze ? 'Check is still snoozed' : 'Check is now active'; ``` -### Maintenance Periods +### [Maintenance Periods](https://ohdear.app/docs/api/maintenance-windows) Maintenance periods allow you to temporarily disable notifications for monitors during planned maintenance windows. @@ -359,7 +427,7 @@ You can delete a maintenance period: $ohDear->deleteMaintenancePeriod($maintenancePeriodId); ``` -### Uptime Metrics +### [Uptime Metrics](https://ohdear.app/docs/api/uptime-metrics) Uptime metrics provide detailed performance and timing data for your monitors over time. Different monitor types (Http, Ping, TCP) provide different metrics. @@ -419,7 +487,7 @@ foreach ($metrics as $metric) { } ``` -### Cron Check Definitions +### [Cron Check Definitions](https://ohdear.app/docs/api/cron-job-monitoring) Cron check definitions allow you to monitor scheduled tasks and ensure they execute on time. You can create different types of cron checks including traditional cron expressions and simple frequency-based checks. @@ -499,7 +567,18 @@ echo $cronCheckDefinition->activeSnooze['ends_at']; $cronCheckDefinition = $ohDear->unsnoozeCronCheckDefinition($cronCheckDefinitionId); ``` -### Broken Links +#### Syncing cron check definitions + +Bulk sync cron check definitions for a monitor — creates, updates, or removes definitions to match the provided list: + +```php +$cronCheckDefinitions = $ohDear->syncCronCheckDefinitions($monitorId, [ + ['name' => 'Backup', 'type' => 'simple', 'frequency_in_minutes' => 60], + ['name' => 'Cleanup', 'type' => 'simple', 'frequency_in_minutes' => 1440], +]); +``` + +### [Broken Links](https://ohdear.app/docs/api/broken-links) The broken links feature crawls your website and identifies links that return HTTP error status codes, helping you maintain a healthy website. @@ -518,7 +597,7 @@ foreach ($brokenLinks as $brokenLink) { } ``` -### Detected Certificates +### [Detected Certificates](https://ohdear.app/docs/api/certificate-health) Detected certificates provide information about SSL certificates that Oh Dear has discovered while monitoring your site, including their details, validity, and fingerprints. @@ -560,7 +639,7 @@ echo "Certificate fingerprint: {$certificate->fingerprint}"; echo "Created at: {$certificate->createdAt}"; ``` -### DNS History Items +### [DNS History Items](https://ohdear.app/docs/api/dns-records) DNS history items track changes to your domain's DNS records over time, helping you monitor DNS propagation and detect unauthorized changes. @@ -587,7 +666,7 @@ foreach ($dnsHistoryItems as $historyItem) { $historyItem = $ohDear->dnsHistoryItem($monitorId, $historyItemId); ``` -### Lighthouse Reports +### [Lighthouse Reports](https://ohdear.app/docs/api/lighthouse) Lighthouse reports provide detailed performance, accessibility, SEO, and best practices analysis of your web pages using Google's Lighthouse auditing tool. @@ -650,7 +729,7 @@ echo "Latest performance score: {$latestReport->performanceScore}/100"; echo "Report generated: {$latestReport->createdAt}"; ``` -### Application Health Checks +### [Application Health Checks](https://ohdear.app/docs/api/application-health) Application health checks monitor custom endpoints in your application to ensure they're responding correctly and returning expected health status information. @@ -689,20 +768,25 @@ foreach ($healthChecks as $healthCheck) { #### Getting history for a specific application health check ```php -// returns an array of OhDear\PhpSdk\Dto\ApplicationHealthCheckHistoryItem $history = $ohDear->applicationHealthCheckHistory($monitorId, $healthCheckId); foreach ($history as $historyItem) { - echo "History Item ID: {$historyItem->id}"; echo "Status: {$historyItem->status}"; echo "Short summary: {$historyItem->shortSummary}"; - echo "Message: {$historyItem->message}"; - echo "Detected at: {$historyItem->detectedAt}"; - echo "Updated at: {$historyItem->updatedAt}"; } ``` -### Sitemap +#### Snoozing and unsnoozing application health checks + +```php +// Snooze for 60 minutes +$healthCheck = $ohDear->snoozeApplicationHealthCheck($monitorId, $healthCheckId, 60); + +// Unsnooze +$healthCheck = $ohDear->unsnoozeApplicationHealthCheck($monitorId, $healthCheckId); +``` + +### [Sitemap](https://ohdear.app/docs/api/sitemap) The sitemap check analyzes your website's XML sitemap(s) to ensure they're accessible and properly formatted, and can also check the reachability of URLs within the sitemaps. @@ -753,7 +837,7 @@ if (!empty($sitemap->sitemaps)) { } ``` -### Mixed Content +### [Mixed Content](https://ohdear.app/docs/api/mixed-content) The mixed content check identifies elements on your HTTPS pages that are loaded over HTTP, which can cause security warnings in browsers and degrade user experience. @@ -771,7 +855,7 @@ foreach ($mixedContentItems as $mixedContent) { } ``` -### Downtime +### [Downtime](https://ohdear.app/docs/api/uptime) Downtime periods track when your monitored sites were unavailable, providing historical data about outages and their duration. @@ -819,6 +903,164 @@ You can delete downtime periods that were recorded incorrectly or are no longer $ohDear->deleteDowntimePeriod($downtimePeriodId); ``` +### [Domain Monitoring](https://ohdear.app/docs/api/domain-monitoring) + +```php +$domainInfo = $ohDear->domain($monitorId); + +echo "Expires at: {$domainInfo->expiresAt}"; +echo "Registered at: {$domainInfo->registeredAt}"; +``` + +### [AI Responses](https://ohdear.app/docs/api/ai-monitoring) + +```php +// List all AI responses +$aiResponses = $ohDear->aiResponses($monitorId); + +// Get a specific AI response +$aiResponse = $ohDear->aiResponse($monitorId, $aiResponseId); + +// Get the latest AI response +$aiResponse = $ohDear->latestAiResponse($monitorId); + +echo "Prompt: {$aiResponse->prompt}"; +echo "Response: {$aiResponse->response}"; +``` + +### [Port Scanning](https://ohdear.app/docs/api/port-scanning) + +```php +// List port scan results +$items = $ohDear->portsHistoryItems($monitorId); + +// Get a specific port scan +$item = $ohDear->portsHistoryItem($monitorId, $portsHistoryItemId); + +echo "Scanned host: {$item->scannedHost}"; +echo "Scan time: {$item->scanTimeMs}ms"; +``` + +### [DNS Blocklist](https://ohdear.app/docs/api/dns-blocklist) + +```php +// List blocklist check results +$items = $ohDear->dnsBlocklistHistoryItems($monitorId); + +// Get a specific blocklist check +$item = $ohDear->dnsBlocklistHistoryItem($monitorId, $dnsBlocklistHistoryItemId); + +echo "Domain: {$item->domain}"; +``` + +### [Tags](https://ohdear.app/docs/api/tags-and-tag-groups) + +```php +$tags = $ohDear->tags(); + +$tag = $ohDear->createTag([ + 'name' => 'production', + 'team_id' => 1, +]); +``` + +### [Tag Groups](https://ohdear.app/docs/api/tags-and-tag-groups) + +```php +$tagGroups = $ohDear->tagGroups(); + +$tagGroup = $ohDear->createTagGroup([ + 'label' => 'Environment', + 'team_id' => 1, +]); + +$tagGroup = $ohDear->updateTagGroup($tagGroupId, [ + 'label' => 'Updated label', +]); + +$ohDear->deleteTagGroup($tagGroupId); +``` + +### [Recurring Maintenance Periods](https://ohdear.app/docs/api/maintenance-windows) + +```php +// List recurring periods for a monitor +$periods = $ohDear->recurringMaintenancePeriods($monitorId); + +// Get a single recurring period +$period = $ohDear->recurringMaintenancePeriod($recurringMaintenancePeriodId); + +// Create +$period = $ohDear->createRecurringMaintenancePeriod([ + 'monitor_id' => $monitorId, + 'name' => 'Weekly maintenance', + 'recurrence_type' => 'weekly', + 'start_time' => '02:00', + 'end_time' => '04:00', + 'days_of_week' => [0], // Sunday +]); + +// Update +$period = $ohDear->updateRecurringMaintenancePeriod($id, [ + 'name' => 'Updated schedule', +]); + +// Delete +$ohDear->deleteRecurringMaintenancePeriod($id); +``` + +### [Notification Destinations](https://ohdear.app/docs/api/notification-destinations) + +Notification destinations can be managed at the monitor, team, tag, and tag group level. + +#### Monitor-level notification destinations + +```php +$destinations = $ohDear->notificationDestinations($monitorId); + +$destination = $ohDear->createNotificationDestination($monitorId, [ + 'channel' => 'mail', + 'destination' => ['mail' => 'alerts@example.com'], +]); + +$destination = $ohDear->updateNotificationDestination($monitorId, $destinationId, [ + 'destination' => ['mail' => 'new@example.com'], +]); + +$ohDear->deleteNotificationDestination($monitorId, $destinationId); +``` + +#### Team-level notification destinations + +```php +$destinations = $ohDear->teamNotificationDestinations(); + +$destination = $ohDear->createTeamNotificationDestination($teamId, [ + 'channel' => 'slack', + 'destination' => ['url' => 'https://hooks.slack.com/...'], +]); + +$destination = $ohDear->updateTeamNotificationDestination($teamId, $destinationId, [...]); + +$ohDear->deleteTeamNotificationDestination($teamId, $destinationId); +``` + +#### Tag and tag group notification destinations + +```php +// Tag destinations +$destinations = $ohDear->tagNotificationDestinations(); +$destination = $ohDear->createTagNotificationDestination($tagId, [...]); +$destination = $ohDear->updateTagNotificationDestination($tagId, $destinationId, [...]); +$ohDear->deleteTagNotificationDestination($tagId, $destinationId); + +// Tag group destinations +$destinations = $ohDear->tagGroupNotificationDestinations($tagGroupId); +$destination = $ohDear->createTagGroupNotificationDestination($tagGroupId, [...]); +$destination = $ohDear->updateTagGroupNotificationDestination($tagGroupId, $destinationId, [...]); +$ohDear->deleteTagGroupNotificationDestination($tagGroupId, $destinationId); +``` + ### Using Saloon requests directly This SDK uses [Saloon](https://docs.saloon.dev) to make the HTTP requests. Instead of using the `OhDear` class, you can the underlying request classes directly. This way, you have full power to customize the requests. diff --git a/composer.json b/composer.json index b15a0f7..b56d824 100644 --- a/composer.json +++ b/composer.json @@ -23,9 +23,9 @@ "saloonphp/saloon": "^3.14" }, "require-dev": { + "laravel/pint": "^1.27", "pestphp/pest": "^2.35|^3.8.2", - "phpstan/phpstan": "^2.1", - "vlucas/phpdotenv": "^5.6.2" + "phpstan/phpstan": "^2.1" }, "autoload": { "psr-4": { @@ -40,7 +40,6 @@ "scripts": { "format": "vendor/bin/pint", "test": "vendor/bin/pest -p", - "real": "php tests/TestSupport/scripts/real-test.php", "analyse": "vendor/bin/phpstan analyse", "baseline": "vendor/bin/phpstan analyse --generate-baseline" }, @@ -54,7 +53,7 @@ }, "extra": { "branch-alias": { - "dev-monitors": "4.0.x-dev" + "dev-master": "4.0.x-dev" } } } diff --git a/scripts/real-test.php b/scripts/real-test.php deleted file mode 100644 index c61bd94..0000000 --- a/scripts/real-test.php +++ /dev/null @@ -1,20 +0,0 @@ -safeLoad(); - -$token = $_ENV['OH_DEAR_API_TOKEN'] ?? null; -$baseUrl = $_ENV['OH_DEAR_BASE_URL'] ?? null; - -$ohDear = new OhDear($token, $baseUrl); - -$monitors = $ohDear->monitors(teamId: 1); - -foreach ($monitors as $monitor) { - dump($monitor->teamId); -} diff --git a/src/Concerns/SupportsAiResponsesEndpoints.php b/src/Concerns/SupportsAiResponsesEndpoints.php new file mode 100644 index 0000000..ae6a290 --- /dev/null +++ b/src/Concerns/SupportsAiResponsesEndpoints.php @@ -0,0 +1,33 @@ +send($request)->dtoOrFail(); + } + + public function aiResponse(int $monitorId, int $aiResponseId): AiResponse + { + $request = new GetAiResponseRequest($monitorId, $aiResponseId); + + return $this->send($request)->dto(); + } + + public function latestAiResponse(int $monitorId): AiResponse + { + $request = new GetLatestAiResponseRequest($monitorId); + + return $this->send($request)->dto(); + } +} diff --git a/src/Concerns/SupportsApplicationHealthChecksEndpoints.php b/src/Concerns/SupportsApplicationHealthChecksEndpoints.php index 92fe5de..6798cdd 100644 --- a/src/Concerns/SupportsApplicationHealthChecksEndpoints.php +++ b/src/Concerns/SupportsApplicationHealthChecksEndpoints.php @@ -2,9 +2,13 @@ namespace OhDear\PhpSdk\Concerns; +use OhDear\PhpSdk\Dto\ApplicationHealthCheck; use OhDear\PhpSdk\Requests\ApplicationHealthChecks\GetApplicationHealthCheckHistoryRequest; use OhDear\PhpSdk\Requests\ApplicationHealthChecks\GetApplicationHealthChecksRequest; +use OhDear\PhpSdk\Requests\ApplicationHealthChecks\SnoozeApplicationHealthCheckRequest; +use OhDear\PhpSdk\Requests\ApplicationHealthChecks\UnsnoozeApplicationHealthCheckRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsApplicationHealthChecksEndpoints { public function applicationHealthChecks(int $monitorId): array @@ -20,4 +24,18 @@ public function applicationHealthCheckHistory(int $monitorId, int $applicationHe return $this->send($request)->dtoOrFail(); } + + public function snoozeApplicationHealthCheck(int $monitorId, int $healthCheckId, int $minutes): ApplicationHealthCheck + { + $request = new SnoozeApplicationHealthCheckRequest($monitorId, $healthCheckId, $minutes); + + return $this->send($request)->dto(); + } + + public function unsnoozeApplicationHealthCheck(int $monitorId, int $healthCheckId): ApplicationHealthCheck + { + $request = new UnsnoozeApplicationHealthCheckRequest($monitorId, $healthCheckId); + + return $this->send($request)->dto(); + } } diff --git a/src/Concerns/SupportsCronCheckDefinitionsEndpoints.php b/src/Concerns/SupportsCronCheckDefinitionsEndpoints.php index db0fa20..0d2ea74 100644 --- a/src/Concerns/SupportsCronCheckDefinitionsEndpoints.php +++ b/src/Concerns/SupportsCronCheckDefinitionsEndpoints.php @@ -7,6 +7,7 @@ use OhDear\PhpSdk\Requests\CronCheckDefinitions\DeleteCronCheckDefinitionRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\GetCronCheckDefinitionsRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\SnoozeCronCheckDefinitionRequest; +use OhDear\PhpSdk\Requests\CronCheckDefinitions\SyncCronCheckDefinitionsRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\UnsnoozeCronCheckDefinitionRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\UpdateCronCheckDefinitionRequest; @@ -45,7 +46,6 @@ public function deleteCronCheckDefinition(int $cronCheckDefinitionId): self $this->send($request); return $this; - } public function snoozeCronCheckDefinition(int $cronCheckDefinitionId, int $minutes): CronCheckDefinition @@ -61,4 +61,11 @@ public function unsnoozeCronCheckDefinition(int $cronCheckDefinitionId): CronChe return $this->send($request)->dtoOrFail(); } + + public function syncCronCheckDefinitions(int $monitorId, array $cronChecks): array + { + $request = new SyncCronCheckDefinitionsRequest($monitorId, $cronChecks); + + return $this->send($request)->dtoOrFail(); + } } diff --git a/src/Concerns/SupportsDetectedCertificatesEndpoints.php b/src/Concerns/SupportsDetectedCertificatesEndpoints.php index 821373d..f4c178c 100644 --- a/src/Concerns/SupportsDetectedCertificatesEndpoints.php +++ b/src/Concerns/SupportsDetectedCertificatesEndpoints.php @@ -6,6 +6,7 @@ use OhDear\PhpSdk\Requests\DetectedCertificates\GetDetectedCertificateRequest; use OhDear\PhpSdk\Requests\DetectedCertificates\GetDetectedCertificatesRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsDetectedCertificatesEndpoints { public function detectedCertificates(int $monitorId): array diff --git a/src/Concerns/SupportsDnsBlocklistHistoryItemsEndpoints.php b/src/Concerns/SupportsDnsBlocklistHistoryItemsEndpoints.php new file mode 100644 index 0000000..7633c00 --- /dev/null +++ b/src/Concerns/SupportsDnsBlocklistHistoryItemsEndpoints.php @@ -0,0 +1,25 @@ +send($request)->dtoOrFail(); + } + + public function dnsBlocklistHistoryItem(int $monitorId, int $dnsBlocklistHistoryItemId): DnsBlocklistHistoryItem + { + $request = new GetDnsBlocklistHistoryItemRequest($monitorId, $dnsBlocklistHistoryItemId); + + return $this->send($request)->dto(); + } +} diff --git a/src/Concerns/SupportsDnsHistoryItemsEndpoints.php b/src/Concerns/SupportsDnsHistoryItemsEndpoints.php index a675216..b45c745 100644 --- a/src/Concerns/SupportsDnsHistoryItemsEndpoints.php +++ b/src/Concerns/SupportsDnsHistoryItemsEndpoints.php @@ -6,6 +6,7 @@ use OhDear\PhpSdk\Requests\DnsHistoryItems\GetDnsHistoryItemRequest; use OhDear\PhpSdk\Requests\DnsHistoryItems\GetDnsHistoryItemsRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsDnsHistoryItemsEndpoints { public function dnsHistoryItems(int $monitorId): array diff --git a/src/Concerns/SupportsDomainEndpoints.php b/src/Concerns/SupportsDomainEndpoints.php new file mode 100644 index 0000000..8602df8 --- /dev/null +++ b/src/Concerns/SupportsDomainEndpoints.php @@ -0,0 +1,17 @@ +send($request)->dto(); + } +} diff --git a/src/Concerns/SupportsDowntimeEndpoints.php b/src/Concerns/SupportsDowntimeEndpoints.php index d8ccc4a..2cb1ef0 100644 --- a/src/Concerns/SupportsDowntimeEndpoints.php +++ b/src/Concerns/SupportsDowntimeEndpoints.php @@ -5,6 +5,7 @@ use OhDear\PhpSdk\Requests\Downtime\DeleteDowntimePeriodRequest; use OhDear\PhpSdk\Requests\Downtime\GetDowntimeRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsDowntimeEndpoints { public function downtime(int $monitorId, string $startedAt, string $endedAt): array diff --git a/src/Concerns/SupportsLighthouseReportsEndpoints.php b/src/Concerns/SupportsLighthouseReportsEndpoints.php index cd2c242..01e7722 100644 --- a/src/Concerns/SupportsLighthouseReportsEndpoints.php +++ b/src/Concerns/SupportsLighthouseReportsEndpoints.php @@ -7,6 +7,7 @@ use OhDear\PhpSdk\Requests\LighthouseReports\GetLighthouseReportRequest; use OhDear\PhpSdk\Requests\LighthouseReports\GetLighthouseReportsRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsLighthouseReportsEndpoints { public function lighthouseReports(int $monitorId): array diff --git a/src/Concerns/SupportsMixedContentEndpoints.php b/src/Concerns/SupportsMixedContentEndpoints.php index 9bf7ab6..6f3b818 100644 --- a/src/Concerns/SupportsMixedContentEndpoints.php +++ b/src/Concerns/SupportsMixedContentEndpoints.php @@ -4,6 +4,7 @@ use OhDear\PhpSdk\Requests\MixedContent\GetMixedContentRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsMixedContentEndpoints { public function mixedContent(int $monitorId): array diff --git a/src/Concerns/SupportsMonitorEndpoints.php b/src/Concerns/SupportsMonitorEndpoints.php index 1415a4f..c9ba3f6 100644 --- a/src/Concerns/SupportsMonitorEndpoints.php +++ b/src/Concerns/SupportsMonitorEndpoints.php @@ -6,14 +6,18 @@ use OhDear\PhpSdk\Dto\Monitor; use OhDear\PhpSdk\Dto\NotificationDestination; use OhDear\PhpSdk\Enums\CheckType; +use OhDear\PhpSdk\Requests\Monitors\AddToBrokenLinksWhitelistRequest; use OhDear\PhpSdk\Requests\Monitors\CreateMonitorRequest; use OhDear\PhpSdk\Requests\Monitors\CreateNotificationDestinationsRequest; use OhDear\PhpSdk\Requests\Monitors\DeleteMonitorRequest; +use OhDear\PhpSdk\Requests\Monitors\DeleteNotificationDestinationRequest; use OhDear\PhpSdk\Requests\Monitors\GetCheckSummaryRequest; +use OhDear\PhpSdk\Requests\Monitors\GetMonitorByUrlRequest; use OhDear\PhpSdk\Requests\Monitors\GetMonitorRequest; use OhDear\PhpSdk\Requests\Monitors\GetMonitorsRequest; use OhDear\PhpSdk\Requests\Monitors\GetNotificationDestinationsRequest; use OhDear\PhpSdk\Requests\Monitors\UpdateMonitorRequest; +use OhDear\PhpSdk\Requests\Monitors\UpdateNotificationDestinationRequest; /** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsMonitorEndpoints @@ -79,4 +83,36 @@ public function createNotificationDestination(int $monitorId, array $properties) return $this->send($request)->dto(); } + + public function monitorByUrl(string $url): Monitor + { + $request = new GetMonitorByUrlRequest($url); + + return $this->send($request)->dto(); + } + + public function addToBrokenLinksWhitelist(int $monitorId, string $url): self + { + $request = new AddToBrokenLinksWhitelistRequest($monitorId, $url); + + $this->send($request); + + return $this; + } + + public function updateNotificationDestination(int $monitorId, int $destinationId, array $data): NotificationDestination + { + $request = new UpdateNotificationDestinationRequest($monitorId, $destinationId, $data); + + return $this->send($request)->dto(); + } + + public function deleteNotificationDestination(int $monitorId, int $destinationId): self + { + $request = new DeleteNotificationDestinationRequest($monitorId, $destinationId); + + $this->send($request); + + return $this; + } } diff --git a/src/Concerns/SupportsNotificationDestinationEndpoints.php b/src/Concerns/SupportsNotificationDestinationEndpoints.php new file mode 100644 index 0000000..2da0670 --- /dev/null +++ b/src/Concerns/SupportsNotificationDestinationEndpoints.php @@ -0,0 +1,111 @@ +send($request)->dto(); + } + + public function createTeamNotificationDestination(int $teamId, array $data): NotificationDestination + { + $request = new CreateTeamNotificationDestinationRequest($teamId, $data); + + return $this->send($request)->dto(); + } + + public function updateTeamNotificationDestination(int $teamId, int $destinationId, array $data): NotificationDestination + { + $request = new UpdateTeamNotificationDestinationRequest($teamId, $destinationId, $data); + + return $this->send($request)->dto(); + } + + public function deleteTeamNotificationDestination(int $teamId, int $destinationId): self + { + $request = new DeleteTeamNotificationDestinationRequest($teamId, $destinationId); + + $this->send($request); + + return $this; + } + + public function tagNotificationDestinations(): array + { + $request = new GetTagNotificationDestinationsRequest; + + return $this->send($request)->dto(); + } + + public function createTagNotificationDestination(int $tagId, array $data): NotificationDestination + { + $request = new CreateTagNotificationDestinationRequest($tagId, $data); + + return $this->send($request)->dto(); + } + + public function updateTagNotificationDestination(int $tagId, int $destinationId, array $data): NotificationDestination + { + $request = new UpdateTagNotificationDestinationRequest($tagId, $destinationId, $data); + + return $this->send($request)->dto(); + } + + public function deleteTagNotificationDestination(int $tagId, int $destinationId): self + { + $request = new DeleteTagNotificationDestinationRequest($tagId, $destinationId); + + $this->send($request); + + return $this; + } + + public function tagGroupNotificationDestinations(int $tagGroupId): array + { + $request = new GetTagGroupNotificationDestinationsRequest($tagGroupId); + + return $this->send($request)->dto(); + } + + public function createTagGroupNotificationDestination(int $tagGroupId, array $data): NotificationDestination + { + $request = new CreateTagGroupNotificationDestinationRequest($tagGroupId, $data); + + return $this->send($request)->dto(); + } + + public function updateTagGroupNotificationDestination(int $tagGroupId, int $destinationId, array $data): NotificationDestination + { + $request = new UpdateTagGroupNotificationDestinationRequest($tagGroupId, $destinationId, $data); + + return $this->send($request)->dto(); + } + + public function deleteTagGroupNotificationDestination(int $tagGroupId, int $destinationId): self + { + $request = new DeleteTagGroupNotificationDestinationRequest($tagGroupId, $destinationId); + + $this->send($request); + + return $this; + } +} diff --git a/src/Concerns/SupportsPortsHistoryItemsEndpoints.php b/src/Concerns/SupportsPortsHistoryItemsEndpoints.php new file mode 100644 index 0000000..3188178 --- /dev/null +++ b/src/Concerns/SupportsPortsHistoryItemsEndpoints.php @@ -0,0 +1,25 @@ +send($request)->dtoOrFail(); + } + + public function portsHistoryItem(int $monitorId, int $portsHistoryItemId): PortsHistoryItem + { + $request = new GetPortsHistoryItemRequest($monitorId, $portsHistoryItemId); + + return $this->send($request)->dto(); + } +} diff --git a/src/Concerns/SupportsRecurringMaintenancePeriodEndpoints.php b/src/Concerns/SupportsRecurringMaintenancePeriodEndpoints.php new file mode 100644 index 0000000..6e3d249 --- /dev/null +++ b/src/Concerns/SupportsRecurringMaintenancePeriodEndpoints.php @@ -0,0 +1,51 @@ +send($request)->dtoOrFail(); + } + + public function recurringMaintenancePeriod(int $recurringMaintenancePeriodId): RecurringMaintenancePeriod + { + $request = new GetRecurringMaintenancePeriodRequest($recurringMaintenancePeriodId); + + return $this->send($request)->dto(); + } + + public function createRecurringMaintenancePeriod(array $data): RecurringMaintenancePeriod + { + $request = new CreateRecurringMaintenancePeriodRequest($data); + + return $this->send($request)->dto(); + } + + public function updateRecurringMaintenancePeriod(int $id, array $data): RecurringMaintenancePeriod + { + $request = new UpdateRecurringMaintenancePeriodRequest($id, $data); + + return $this->send($request)->dto(); + } + + public function deleteRecurringMaintenancePeriod(int $id): self + { + $request = new DeleteRecurringMaintenancePeriodRequest($id); + + $this->send($request); + + return $this; + } +} diff --git a/src/Concerns/SupportsSitemapEndpoints.php b/src/Concerns/SupportsSitemapEndpoints.php index aaec19f..642de57 100644 --- a/src/Concerns/SupportsSitemapEndpoints.php +++ b/src/Concerns/SupportsSitemapEndpoints.php @@ -5,6 +5,7 @@ use OhDear\PhpSdk\Dto\Sitemap; use OhDear\PhpSdk\Requests\Sitemap\GetSitemapRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsSitemapEndpoints { public function sitemap(int $monitorId): Sitemap diff --git a/src/Concerns/SupportsStatusPageEndpoints.php b/src/Concerns/SupportsStatusPageEndpoints.php index e32fdc7..ba51736 100644 --- a/src/Concerns/SupportsStatusPageEndpoints.php +++ b/src/Concerns/SupportsStatusPageEndpoints.php @@ -4,11 +4,16 @@ use OhDear\PhpSdk\Dto\StatusPage; use OhDear\PhpSdk\Dto\StatusPageUpdate; +use OhDear\PhpSdk\Requests\StatusPages\AddStatusPageMonitorsRequest; +use OhDear\PhpSdk\Requests\StatusPages\CreateStatusPageRequest; use OhDear\PhpSdk\Requests\StatusPages\CreateStatusPageUpdateRequest; +use OhDear\PhpSdk\Requests\StatusPages\DeleteStatusPageMonitorRequest; use OhDear\PhpSdk\Requests\StatusPages\DeleteStatusPageRequest; use OhDear\PhpSdk\Requests\StatusPages\DeleteStatusPageUpdateRequest; use OhDear\PhpSdk\Requests\StatusPages\GetStatusPageRequest; use OhDear\PhpSdk\Requests\StatusPages\GetStatusPagesRequest; +use OhDear\PhpSdk\Requests\StatusPages\GetStatusPageUpdatesRequest; +use OhDear\PhpSdk\Requests\StatusPages\UpdateStatusPageUpdateRequest; /** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsStatusPageEndpoints @@ -55,4 +60,41 @@ public function deleteStatusPageUpdate(int $statusPageUpdateId): self return $this; } + + public function createStatusPage(array $data): StatusPage + { + $request = new CreateStatusPageRequest($data); + + return $this->send($request)->dto(); + } + + public function addStatusPageMonitors(int $statusPageId, array $data): StatusPage + { + $request = new AddStatusPageMonitorsRequest($statusPageId, $data); + + return $this->send($request)->dto(); + } + + public function deleteStatusPageMonitor(int $statusPageId, int $monitorId): self + { + $request = new DeleteStatusPageMonitorRequest($statusPageId, $monitorId); + + $this->send($request); + + return $this; + } + + public function statusPageUpdates(int $statusPageId): array + { + $request = new GetStatusPageUpdatesRequest($statusPageId); + + return $this->send($request)->dtoOrFail(); + } + + public function updateStatusPageUpdate(int $statusPageUpdateId, array $data): StatusPageUpdate + { + $request = new UpdateStatusPageUpdateRequest($statusPageUpdateId, $data); + + return $this->send($request)->dto(); + } } diff --git a/src/Concerns/SupportsStatusPageUpdateTemplateEndpoints.php b/src/Concerns/SupportsStatusPageUpdateTemplateEndpoints.php new file mode 100644 index 0000000..976f965 --- /dev/null +++ b/src/Concerns/SupportsStatusPageUpdateTemplateEndpoints.php @@ -0,0 +1,43 @@ +send($request)->dtoOrFail(); + } + + public function createStatusPageUpdateTemplate(array $data): StatusPageUpdateTemplate + { + $request = new CreateStatusPageUpdateTemplateRequest($data); + + return $this->send($request)->dto(); + } + + public function updateStatusPageUpdateTemplate(int $id, array $data): StatusPageUpdateTemplate + { + $request = new UpdateStatusPageUpdateTemplateRequest($id, $data); + + return $this->send($request)->dto(); + } + + public function deleteStatusPageUpdateTemplate(int $id): self + { + $request = new DeleteStatusPageUpdateTemplateRequest($id); + + $this->send($request); + + return $this; + } +} diff --git a/src/Concerns/SupportsTagEndpoints.php b/src/Concerns/SupportsTagEndpoints.php new file mode 100644 index 0000000..fd3ac95 --- /dev/null +++ b/src/Concerns/SupportsTagEndpoints.php @@ -0,0 +1,25 @@ +send($request)->dtoOrFail(); + } + + public function createTag(array $data): Tag + { + $request = new CreateTagRequest($data); + + return $this->send($request)->dto(); + } +} diff --git a/src/Concerns/SupportsTagGroupEndpoints.php b/src/Concerns/SupportsTagGroupEndpoints.php new file mode 100644 index 0000000..4c6ba6c --- /dev/null +++ b/src/Concerns/SupportsTagGroupEndpoints.php @@ -0,0 +1,43 @@ +send($request)->dtoOrFail(); + } + + public function createTagGroup(array $data): TagGroup + { + $request = new CreateTagGroupRequest($data); + + return $this->send($request)->dto(); + } + + public function updateTagGroup(int $tagGroupId, array $data): TagGroup + { + $request = new UpdateTagGroupRequest($tagGroupId, $data); + + return $this->send($request)->dto(); + } + + public function deleteTagGroup(int $tagGroupId): self + { + $request = new DeleteTagGroupRequest($tagGroupId); + + $this->send($request); + + return $this; + } +} diff --git a/src/Concerns/SupportsUptimeEndpoints.php b/src/Concerns/SupportsUptimeEndpoints.php index 82ec7bf..59b5e56 100644 --- a/src/Concerns/SupportsUptimeEndpoints.php +++ b/src/Concerns/SupportsUptimeEndpoints.php @@ -6,6 +6,7 @@ use OhDear\PhpSdk\Enums\UptimeSplit; use OhDear\PhpSdk\Requests\Uptime\GetUptimeRequest; +/** @mixin \OhDear\PhpSdk\OhDear */ trait SupportsUptimeEndpoints { /** @return list */ diff --git a/src/Dto/AiResponse.php b/src/Dto/AiResponse.php new file mode 100644 index 0000000..66af510 --- /dev/null +++ b/src/Dto/AiResponse.php @@ -0,0 +1,48 @@ + self::fromResponse($item), $items); + } +} diff --git a/src/Dto/ApplicationHealthCheck.php b/src/Dto/ApplicationHealthCheck.php index 2febfab..44bde2e 100644 --- a/src/Dto/ApplicationHealthCheck.php +++ b/src/Dto/ApplicationHealthCheck.php @@ -25,13 +25,13 @@ public static function fromResponse(array $data): self id: $data['id'], name: $data['name'], label: $data['label'], - status: $data['status'], - message: $data['message'], + status: $data['status'] ?? null, + message: $data['message'] ?? null, meta: $data['meta'] ?? [], - shortSummary: $data['short_summary'], - detectedAt: $data['detected_at'], - updatedAt: $data['updated_at'], - activeSnooze: $data['active_snooze'], + shortSummary: $data['short_summary'] ?? null, + detectedAt: $data['detected_at'] ?? null, + updatedAt: $data['updated_at'] ?? null, + activeSnooze: $data['active_snooze'] ?? null, ); } diff --git a/src/Dto/ApplicationHealthCheckHistoryItem.php b/src/Dto/ApplicationHealthCheckHistoryItem.php index b1b7a3a..418f960 100644 --- a/src/Dto/ApplicationHealthCheckHistoryItem.php +++ b/src/Dto/ApplicationHealthCheckHistoryItem.php @@ -22,8 +22,8 @@ public static function fromResponse(array $data): self id: $data['id'], status: $data['status'], shortSummary: $data['short_summary'], - message: $data['message'], - meta: $data['meta'], + message: $data['message'] ?? null, + meta: $data['meta'] ?? null, detectedAt: $data['detected_at'], updatedAt: $data['updated_at'], ); diff --git a/src/Dto/BrokenLink.php b/src/Dto/BrokenLink.php index 690ad8b..159afb7 100644 --- a/src/Dto/BrokenLink.php +++ b/src/Dto/BrokenLink.php @@ -17,7 +17,7 @@ public function __construct( public static function fromResponse(array $data): self { return new self( - statusCode: $data['status_code'], + statusCode: $data['status_code'] ?? null, crawledUrl: $data['crawled_url'], relativeCrawledUrl: $data['relative_crawled_url'], foundOnUrl: $data['found_on_url'], diff --git a/src/Dto/CertificateHealth.php b/src/Dto/CertificateHealth.php index 7e9ec32..802be6b 100644 --- a/src/Dto/CertificateHealth.php +++ b/src/Dto/CertificateHealth.php @@ -19,33 +19,21 @@ public static function fromResponse(array $data): self ); } - /** - * Get certificate issuer - */ public function getIssuer(): ?string { return $this->certificateDetails['issuer'] ?? null; } - /** - * Get certificate valid from date - */ public function getValidFrom(): ?string { return $this->certificateDetails['valid_from'] ?? null; } - /** - * Get certificate valid until date - */ public function getValidUntil(): ?string { return $this->certificateDetails['valid_until'] ?? null; } - /** - * Check if a specific certificate check passed - */ public function checkPassed(string $checkType): bool { foreach ($this->certificateChecks as $check) { @@ -57,17 +45,11 @@ public function checkPassed(string $checkType): bool return false; } - /** - * Get all failed certificate checks - */ public function getFailedChecks(): array { return array_filter($this->certificateChecks, fn ($check) => ! ($check['passed'] ?? false)); } - /** - * Check if certificate is healthy (all checks passed) - */ public function isHealthy(): bool { return empty($this->getFailedChecks()); diff --git a/src/Dto/Check.php b/src/Dto/Check.php index fe2f2b2..da090c1 100644 --- a/src/Dto/Check.php +++ b/src/Dto/Check.php @@ -13,6 +13,7 @@ public function __construct( public ?string $latestRunResult, public ?string $summary, public array $settings, + public ?float $averageResponseTimeInMs, public ?array $activeSnooze, ) {} @@ -27,6 +28,7 @@ public static function fromResponse(array $data): self latestRunResult: $data['latest_run_result'] ?? null, summary: $data['summary'] ?? null, settings: $data['settings'] ?? [], + averageResponseTimeInMs: $data['average_response_time_in_ms'] ?? null, activeSnooze: $data['active_snooze'] ?? null, ); } diff --git a/src/Dto/DetectedCertificate.php b/src/Dto/DetectedCertificate.php index cada93e..4740a22 100644 --- a/src/Dto/DetectedCertificate.php +++ b/src/Dto/DetectedCertificate.php @@ -21,7 +21,7 @@ public static function fromResponse(array $data): self id: $data['id'], monitorId: $data['monitor_id'], fingerprint: $data['fingerprint'], - certificateDetails: $data['certificate_details'], + certificateDetails: $data['certificate_details'] ?? null, createdAt: $data['created_at'], updatedAt: $data['updated_at'], ); diff --git a/src/Dto/DnsBlocklistHistoryItem.php b/src/Dto/DnsBlocklistHistoryItem.php new file mode 100644 index 0000000..706dd14 --- /dev/null +++ b/src/Dto/DnsBlocklistHistoryItem.php @@ -0,0 +1,32 @@ + self::fromResponse($item), $items); + } +} diff --git a/src/Dto/DnsHistoryItem.php b/src/Dto/DnsHistoryItem.php index 9d4063e..e612889 100644 --- a/src/Dto/DnsHistoryItem.php +++ b/src/Dto/DnsHistoryItem.php @@ -11,7 +11,7 @@ public function __construct( public array $authoritativeNameservers, public array $dnsRecords, public array $rawDnsRecords, - public mixed $issues, + public ?array $issues, public string $diffSummary, public string $createdAt, ) {} @@ -23,7 +23,7 @@ public static function fromResponse(array $data): self authoritativeNameservers: $data['authoritative_nameservers'] ?? [], dnsRecords: $data['dns_records'] ?? [], rawDnsRecords: $data['raw_dns_records'] ?? [], - issues: $data['issues'], + issues: $data['issues'] ?? null, diffSummary: $data['diff_summary'], createdAt: $data['created_at'], ); diff --git a/src/Dto/DomainInfo.php b/src/Dto/DomainInfo.php new file mode 100644 index 0000000..e8fe045 --- /dev/null +++ b/src/Dto/DomainInfo.php @@ -0,0 +1,29 @@ + self::fromResponse($item), $items); + } +} diff --git a/src/Dto/RecurringMaintenancePeriod.php b/src/Dto/RecurringMaintenancePeriod.php new file mode 100644 index 0000000..3eee8ea --- /dev/null +++ b/src/Dto/RecurringMaintenancePeriod.php @@ -0,0 +1,44 @@ + self::fromResponse($item), $items); + } +} diff --git a/src/Dto/StatusPage.php b/src/Dto/StatusPage.php index 0f3ae39..4694916 100644 --- a/src/Dto/StatusPage.php +++ b/src/Dto/StatusPage.php @@ -17,8 +17,10 @@ public function __construct( public ?string $summarizedStatus, public ?array $updates, public ?array $monitors, - public string $createdAt, - public string $updatedAt, + public bool $preventIndexing = false, + public bool $addHstsHeader = false, + public string $createdAt = '', + public string $updatedAt = '', ) {} public static function fromResponse(array $data): self @@ -26,7 +28,7 @@ public static function fromResponse(array $data): self return new self( id: $data['id'], team: $data['team'] ?? null, - title: $data['title'], + title: $data['title'] ?? null, domain: $data['domain'] ?? null, secret: $data['secret'] ?? null, badgeId: $data['badge_id'] ?? null, @@ -36,8 +38,10 @@ public static function fromResponse(array $data): self summarizedStatus: $data['summarized_status'] ?? null, updates: $data['updates'] ?? [], monitors: $data['monitors'] ?? [], - createdAt: $data['created_at'], - updatedAt: $data['updated_at'], + preventIndexing: $data['prevent_indexing'] ?? false, + addHstsHeader: $data['add_hsts_header'] ?? false, + createdAt: $data['created_at'] ?? '', + updatedAt: $data['updated_at'] ?? '', ); } diff --git a/src/Dto/StatusPageUpdate.php b/src/Dto/StatusPageUpdate.php index e251e50..d05126a 100644 --- a/src/Dto/StatusPageUpdate.php +++ b/src/Dto/StatusPageUpdate.php @@ -1,7 +1,5 @@ self::fromResponse($item), $items); + } +} diff --git a/src/Dto/Tag.php b/src/Dto/Tag.php new file mode 100644 index 0000000..ccec132 --- /dev/null +++ b/src/Dto/Tag.php @@ -0,0 +1,36 @@ + self::fromResponse($item), $items); + } +} diff --git a/src/Dto/TagGroup.php b/src/Dto/TagGroup.php new file mode 100644 index 0000000..0bb3917 --- /dev/null +++ b/src/Dto/TagGroup.php @@ -0,0 +1,34 @@ + self::fromResponse($item), $items); + } +} diff --git a/src/Dto/Uptime.php b/src/Dto/Uptime.php index fae9579..03bc2ee 100644 --- a/src/Dto/Uptime.php +++ b/src/Dto/Uptime.php @@ -1,7 +1,5 @@ response = $response; } } diff --git a/src/Exceptions/ValidationException.php b/src/Exceptions/ValidationException.php index 2d3fea1..f0d09ad 100644 --- a/src/Exceptions/ValidationException.php +++ b/src/Exceptions/ValidationException.php @@ -56,12 +56,6 @@ public function hasErrorsForField(string $field): bool /** @return array */ public function getAllErrorMessages(): array { - $messages = []; - - foreach ($this->errors as $fieldErrors) { - $messages = array_merge($messages, $fieldErrors); - } - - return $messages; + return array_merge(...array_values($this->errors)); } } diff --git a/src/OhDear.php b/src/OhDear.php index 7cc9256..bee098d 100644 --- a/src/OhDear.php +++ b/src/OhDear.php @@ -2,21 +2,30 @@ namespace OhDear\PhpSdk; +use OhDear\PhpSdk\Concerns\SupportsAiResponsesEndpoints; use OhDear\PhpSdk\Concerns\SupportsApplicationHealthChecksEndpoints; use OhDear\PhpSdk\Concerns\SupportsBrokenLinksEndpoints; use OhDear\PhpSdk\Concerns\SupportsCertificateHealthEndpoints; use OhDear\PhpSdk\Concerns\SupportsCheckEndpoints; use OhDear\PhpSdk\Concerns\SupportsCronCheckDefinitionsEndpoints; use OhDear\PhpSdk\Concerns\SupportsDetectedCertificatesEndpoints; +use OhDear\PhpSdk\Concerns\SupportsDnsBlocklistHistoryItemsEndpoints; use OhDear\PhpSdk\Concerns\SupportsDnsHistoryItemsEndpoints; +use OhDear\PhpSdk\Concerns\SupportsDomainEndpoints; use OhDear\PhpSdk\Concerns\SupportsDowntimeEndpoints; use OhDear\PhpSdk\Concerns\SupportsLighthouseReportsEndpoints; use OhDear\PhpSdk\Concerns\SupportsMaintenancePeriodEndpoints; use OhDear\PhpSdk\Concerns\SupportsMeEndpoint; use OhDear\PhpSdk\Concerns\SupportsMixedContentEndpoints; use OhDear\PhpSdk\Concerns\SupportsMonitorEndpoints; +use OhDear\PhpSdk\Concerns\SupportsNotificationDestinationEndpoints; +use OhDear\PhpSdk\Concerns\SupportsPortsHistoryItemsEndpoints; +use OhDear\PhpSdk\Concerns\SupportsRecurringMaintenancePeriodEndpoints; use OhDear\PhpSdk\Concerns\SupportsSitemapEndpoints; use OhDear\PhpSdk\Concerns\SupportsStatusPageEndpoints; +use OhDear\PhpSdk\Concerns\SupportsStatusPageUpdateTemplateEndpoints; +use OhDear\PhpSdk\Concerns\SupportsTagEndpoints; +use OhDear\PhpSdk\Concerns\SupportsTagGroupEndpoints; use OhDear\PhpSdk\Concerns\SupportsUptimeEndpoints; use OhDear\PhpSdk\Concerns\SupportsUptimeMetricsEndpoints; use OhDear\PhpSdk\Exceptions\OhDearException; @@ -36,21 +45,30 @@ class OhDear extends Connector implements HasPagination { use AcceptsJson; use AlwaysThrowOnErrors; + use SupportsAiResponsesEndpoints; use SupportsApplicationHealthChecksEndpoints; use SupportsBrokenLinksEndpoints; use SupportsCertificateHealthEndpoints; use SupportsCheckEndpoints; use SupportsCronCheckDefinitionsEndpoints; use SupportsDetectedCertificatesEndpoints; + use SupportsDnsBlocklistHistoryItemsEndpoints; use SupportsDnsHistoryItemsEndpoints; + use SupportsDomainEndpoints; use SupportsDowntimeEndpoints; use SupportsLighthouseReportsEndpoints; use SupportsMaintenancePeriodEndpoints; use SupportsMeEndpoint; use SupportsMixedContentEndpoints; use SupportsMonitorEndpoints; + use SupportsNotificationDestinationEndpoints; + use SupportsPortsHistoryItemsEndpoints; + use SupportsRecurringMaintenancePeriodEndpoints; use SupportsSitemapEndpoints; use SupportsStatusPageEndpoints; + use SupportsStatusPageUpdateTemplateEndpoints; + use SupportsTagEndpoints; + use SupportsTagGroupEndpoints; use SupportsUptimeEndpoints; use SupportsUptimeMetricsEndpoints; diff --git a/src/Requests/AiResponses/GetAiResponseRequest.php b/src/Requests/AiResponses/GetAiResponseRequest.php new file mode 100644 index 0000000..b35df85 --- /dev/null +++ b/src/Requests/AiResponses/GetAiResponseRequest.php @@ -0,0 +1,28 @@ +monitorId}/ai-responses/{$this->aiResponseId}"; + } + + public function createDtoFromResponse(Response $response): AiResponse + { + return AiResponse::fromResponse($response->json()); + } +} diff --git a/src/Requests/AiResponses/GetAiResponsesRequest.php b/src/Requests/AiResponses/GetAiResponsesRequest.php new file mode 100644 index 0000000..51336dd --- /dev/null +++ b/src/Requests/AiResponses/GetAiResponsesRequest.php @@ -0,0 +1,27 @@ +monitorId}/ai-responses"; + } + + public function createDtoFromResponse(Response $response): array + { + return AiResponse::collect($response->json('data')); + } +} diff --git a/src/Requests/AiResponses/GetLatestAiResponseRequest.php b/src/Requests/AiResponses/GetLatestAiResponseRequest.php new file mode 100644 index 0000000..43f7da8 --- /dev/null +++ b/src/Requests/AiResponses/GetLatestAiResponseRequest.php @@ -0,0 +1,27 @@ +monitorId}/ai-responses/latest"; + } + + public function createDtoFromResponse(Response $response): AiResponse + { + return AiResponse::fromResponse($response->json()); + } +} diff --git a/src/Requests/ApplicationHealthChecks/SnoozeApplicationHealthCheckRequest.php b/src/Requests/ApplicationHealthChecks/SnoozeApplicationHealthCheckRequest.php new file mode 100644 index 0000000..5c2ce25 --- /dev/null +++ b/src/Requests/ApplicationHealthChecks/SnoozeApplicationHealthCheckRequest.php @@ -0,0 +1,40 @@ +monitorId}/application-health-checks/{$this->healthCheckId}/snooze"; + } + + protected function defaultBody(): array + { + return [ + 'minutes' => $this->minutes, + ]; + } + + public function createDtoFromResponse(Response $response): ApplicationHealthCheck + { + return ApplicationHealthCheck::fromResponse($response->json()); + } +} diff --git a/src/Requests/ApplicationHealthChecks/UnsnoozeApplicationHealthCheckRequest.php b/src/Requests/ApplicationHealthChecks/UnsnoozeApplicationHealthCheckRequest.php new file mode 100644 index 0000000..f7d4b48 --- /dev/null +++ b/src/Requests/ApplicationHealthChecks/UnsnoozeApplicationHealthCheckRequest.php @@ -0,0 +1,28 @@ +monitorId}/application-health-checks/{$this->healthCheckId}/unsnooze"; + } + + public function createDtoFromResponse(Response $response): ApplicationHealthCheck + { + return ApplicationHealthCheck::fromResponse($response->json()); + } +} diff --git a/src/Requests/CronCheckDefinitions/SyncCronCheckDefinitionsRequest.php b/src/Requests/CronCheckDefinitions/SyncCronCheckDefinitionsRequest.php new file mode 100644 index 0000000..c319746 --- /dev/null +++ b/src/Requests/CronCheckDefinitions/SyncCronCheckDefinitionsRequest.php @@ -0,0 +1,39 @@ +monitorId}/cron-checks/sync"; + } + + protected function defaultBody(): array + { + return [ + 'cron_checks' => $this->cronChecks, + ]; + } + + public function createDtoFromResponse(Response $response): array + { + return CronCheckDefinition::collect($response->json('data')); + } +} diff --git a/src/Requests/DnsBlocklistHistoryItems/GetDnsBlocklistHistoryItemRequest.php b/src/Requests/DnsBlocklistHistoryItems/GetDnsBlocklistHistoryItemRequest.php new file mode 100644 index 0000000..9f2063b --- /dev/null +++ b/src/Requests/DnsBlocklistHistoryItems/GetDnsBlocklistHistoryItemRequest.php @@ -0,0 +1,28 @@ +monitorId}/dns-blocklist-history-items/{$this->dnsBlocklistHistoryItemId}"; + } + + public function createDtoFromResponse(Response $response): DnsBlocklistHistoryItem + { + return DnsBlocklistHistoryItem::fromResponse($response->json()); + } +} diff --git a/src/Requests/DnsBlocklistHistoryItems/GetDnsBlocklistHistoryItemsRequest.php b/src/Requests/DnsBlocklistHistoryItems/GetDnsBlocklistHistoryItemsRequest.php new file mode 100644 index 0000000..d3e7011 --- /dev/null +++ b/src/Requests/DnsBlocklistHistoryItems/GetDnsBlocklistHistoryItemsRequest.php @@ -0,0 +1,27 @@ +monitorId}/dns-blocklist-history-items"; + } + + public function createDtoFromResponse(Response $response): array + { + return DnsBlocklistHistoryItem::collect($response->json('data')); + } +} diff --git a/src/Requests/Domain/GetDomainRequest.php b/src/Requests/Domain/GetDomainRequest.php new file mode 100644 index 0000000..772656a --- /dev/null +++ b/src/Requests/Domain/GetDomainRequest.php @@ -0,0 +1,27 @@ +monitorId}/domain"; + } + + public function createDtoFromResponse(Response $response): DomainInfo + { + return DomainInfo::fromResponse($response->json()); + } +} diff --git a/src/Requests/MeRequest.php b/src/Requests/MeRequest.php index 31132bd..34039a3 100644 --- a/src/Requests/MeRequest.php +++ b/src/Requests/MeRequest.php @@ -11,9 +11,6 @@ class MeRequest extends Request { protected Method $method = Method::GET; - public function __construct( - ) {} - public function resolveEndpoint(): string { return '/me'; diff --git a/src/Requests/Monitors/AddToBrokenLinksWhitelistRequest.php b/src/Requests/Monitors/AddToBrokenLinksWhitelistRequest.php new file mode 100644 index 0000000..0dc81a8 --- /dev/null +++ b/src/Requests/Monitors/AddToBrokenLinksWhitelistRequest.php @@ -0,0 +1,32 @@ +monitorId}/add-to-broken-links-whitelist"; + } + + protected function defaultBody(): array + { + return [ + 'whitelistUrl' => $this->url, + ]; + } +} diff --git a/src/Requests/Monitors/DeleteNotificationDestinationRequest.php b/src/Requests/Monitors/DeleteNotificationDestinationRequest.php new file mode 100644 index 0000000..8e0c084 --- /dev/null +++ b/src/Requests/Monitors/DeleteNotificationDestinationRequest.php @@ -0,0 +1,21 @@ +monitorId}/notification-destinations/{$this->destinationId}"; + } +} diff --git a/src/Requests/Monitors/GetCheckSummaryRequest.php b/src/Requests/Monitors/GetCheckSummaryRequest.php index cce675d..1ad0681 100644 --- a/src/Requests/Monitors/GetCheckSummaryRequest.php +++ b/src/Requests/Monitors/GetCheckSummaryRequest.php @@ -19,13 +19,11 @@ public function __construct( public function resolveEndpoint(): string { - return "monitors/{$this->monitorId}/check-summary/{$this->checkType->value}"; + return "/monitors/{$this->monitorId}/check-summary/{$this->checkType->value}"; } public function createDtoFromResponse(Response $response): CheckSummary { - $data = $response->json(); - - return CheckSummary::fromResponse($data); + return CheckSummary::fromResponse($response->json()); } } diff --git a/src/Requests/Monitors/GetMonitorByUrlRequest.php b/src/Requests/Monitors/GetMonitorByUrlRequest.php new file mode 100644 index 0000000..8e10632 --- /dev/null +++ b/src/Requests/Monitors/GetMonitorByUrlRequest.php @@ -0,0 +1,27 @@ +monitorUrl); + } + + public function createDtoFromResponse(Response $response): Monitor + { + return Monitor::fromResponse($response->json()); + } +} diff --git a/src/Requests/Monitors/UpdateNotificationDestinationRequest.php b/src/Requests/Monitors/UpdateNotificationDestinationRequest.php new file mode 100644 index 0000000..ceaa2ff --- /dev/null +++ b/src/Requests/Monitors/UpdateNotificationDestinationRequest.php @@ -0,0 +1,38 @@ +monitorId}/notification-destinations/{$this->destinationId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/NotificationDestinations/CreateTagGroupNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/CreateTagGroupNotificationDestinationRequest.php new file mode 100644 index 0000000..cef5b0b --- /dev/null +++ b/src/Requests/NotificationDestinations/CreateTagGroupNotificationDestinationRequest.php @@ -0,0 +1,37 @@ +tagGroupId}/notification-destinations"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/NotificationDestinations/CreateTagNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/CreateTagNotificationDestinationRequest.php new file mode 100644 index 0000000..eae43b5 --- /dev/null +++ b/src/Requests/NotificationDestinations/CreateTagNotificationDestinationRequest.php @@ -0,0 +1,37 @@ +tagId}/notification-destinations"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/NotificationDestinations/CreateTeamNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/CreateTeamNotificationDestinationRequest.php new file mode 100644 index 0000000..64b5f62 --- /dev/null +++ b/src/Requests/NotificationDestinations/CreateTeamNotificationDestinationRequest.php @@ -0,0 +1,37 @@ +teamId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/NotificationDestinations/DeleteTagGroupNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/DeleteTagGroupNotificationDestinationRequest.php new file mode 100644 index 0000000..ae93ca6 --- /dev/null +++ b/src/Requests/NotificationDestinations/DeleteTagGroupNotificationDestinationRequest.php @@ -0,0 +1,21 @@ +tagGroupId}/notification-destinations/{$this->destinationId}"; + } +} diff --git a/src/Requests/NotificationDestinations/DeleteTagNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/DeleteTagNotificationDestinationRequest.php new file mode 100644 index 0000000..8bf9cb0 --- /dev/null +++ b/src/Requests/NotificationDestinations/DeleteTagNotificationDestinationRequest.php @@ -0,0 +1,21 @@ +tagId}/notification-destinations/destination/{$this->destinationId}"; + } +} diff --git a/src/Requests/NotificationDestinations/DeleteTeamNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/DeleteTeamNotificationDestinationRequest.php new file mode 100644 index 0000000..c881d1d --- /dev/null +++ b/src/Requests/NotificationDestinations/DeleteTeamNotificationDestinationRequest.php @@ -0,0 +1,21 @@ +teamId}/destination/{$this->destinationId}"; + } +} diff --git a/src/Requests/NotificationDestinations/GetTagGroupNotificationDestinationsRequest.php b/src/Requests/NotificationDestinations/GetTagGroupNotificationDestinationsRequest.php new file mode 100644 index 0000000..0307fa6 --- /dev/null +++ b/src/Requests/NotificationDestinations/GetTagGroupNotificationDestinationsRequest.php @@ -0,0 +1,27 @@ +tagGroupId}/notification-destinations"; + } + + public function createDtoFromResponse(Response $response): array + { + return NotificationDestination::collect($response); + } +} diff --git a/src/Requests/NotificationDestinations/GetTagNotificationDestinationsRequest.php b/src/Requests/NotificationDestinations/GetTagNotificationDestinationsRequest.php new file mode 100644 index 0000000..56fbf36 --- /dev/null +++ b/src/Requests/NotificationDestinations/GetTagNotificationDestinationsRequest.php @@ -0,0 +1,23 @@ +tagGroupId}/notification-destinations/{$this->destinationId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/NotificationDestinations/UpdateTagNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/UpdateTagNotificationDestinationRequest.php new file mode 100644 index 0000000..ee2bfe4 --- /dev/null +++ b/src/Requests/NotificationDestinations/UpdateTagNotificationDestinationRequest.php @@ -0,0 +1,38 @@ +tagId}/notification-destinations/{$this->destinationId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/NotificationDestinations/UpdateTeamNotificationDestinationRequest.php b/src/Requests/NotificationDestinations/UpdateTeamNotificationDestinationRequest.php new file mode 100644 index 0000000..a9a58b4 --- /dev/null +++ b/src/Requests/NotificationDestinations/UpdateTeamNotificationDestinationRequest.php @@ -0,0 +1,38 @@ +teamId}/destination/{$this->destinationId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): NotificationDestination + { + return NotificationDestination::fromResponse($response->json()); + } +} diff --git a/src/Requests/PortsHistoryItems/GetPortsHistoryItemRequest.php b/src/Requests/PortsHistoryItems/GetPortsHistoryItemRequest.php new file mode 100644 index 0000000..33f075e --- /dev/null +++ b/src/Requests/PortsHistoryItems/GetPortsHistoryItemRequest.php @@ -0,0 +1,28 @@ +monitorId}/ports-history-items/{$this->portsHistoryItemId}"; + } + + public function createDtoFromResponse(Response $response): PortsHistoryItem + { + return PortsHistoryItem::fromResponse($response->json()); + } +} diff --git a/src/Requests/PortsHistoryItems/GetPortsHistoryItemsRequest.php b/src/Requests/PortsHistoryItems/GetPortsHistoryItemsRequest.php new file mode 100644 index 0000000..0c3b6d8 --- /dev/null +++ b/src/Requests/PortsHistoryItems/GetPortsHistoryItemsRequest.php @@ -0,0 +1,27 @@ +monitorId}/ports-history-items"; + } + + public function createDtoFromResponse(Response $response): array + { + return PortsHistoryItem::collect($response->json('data')); + } +} diff --git a/src/Requests/RecurringMaintenancePeriods/CreateRecurringMaintenancePeriodRequest.php b/src/Requests/RecurringMaintenancePeriods/CreateRecurringMaintenancePeriodRequest.php new file mode 100644 index 0000000..c36c74b --- /dev/null +++ b/src/Requests/RecurringMaintenancePeriods/CreateRecurringMaintenancePeriodRequest.php @@ -0,0 +1,36 @@ +data; + } + + public function createDtoFromResponse(Response $response): RecurringMaintenancePeriod + { + return RecurringMaintenancePeriod::fromResponse($response->json()); + } +} diff --git a/src/Requests/RecurringMaintenancePeriods/DeleteRecurringMaintenancePeriodRequest.php b/src/Requests/RecurringMaintenancePeriods/DeleteRecurringMaintenancePeriodRequest.php new file mode 100644 index 0000000..ba95850 --- /dev/null +++ b/src/Requests/RecurringMaintenancePeriods/DeleteRecurringMaintenancePeriodRequest.php @@ -0,0 +1,20 @@ +recurringMaintenancePeriodId}"; + } +} diff --git a/src/Requests/RecurringMaintenancePeriods/GetRecurringMaintenancePeriodRequest.php b/src/Requests/RecurringMaintenancePeriods/GetRecurringMaintenancePeriodRequest.php new file mode 100644 index 0000000..7fbd18d --- /dev/null +++ b/src/Requests/RecurringMaintenancePeriods/GetRecurringMaintenancePeriodRequest.php @@ -0,0 +1,27 @@ +recurringMaintenancePeriodId}"; + } + + public function createDtoFromResponse(Response $response): RecurringMaintenancePeriod + { + return RecurringMaintenancePeriod::fromResponse($response->json()); + } +} diff --git a/src/Requests/RecurringMaintenancePeriods/GetRecurringMaintenancePeriodsRequest.php b/src/Requests/RecurringMaintenancePeriods/GetRecurringMaintenancePeriodsRequest.php new file mode 100644 index 0000000..40cfb2f --- /dev/null +++ b/src/Requests/RecurringMaintenancePeriods/GetRecurringMaintenancePeriodsRequest.php @@ -0,0 +1,27 @@ +monitorId}/recurring-maintenance-periods"; + } + + public function createDtoFromResponse(Response $response): array + { + return RecurringMaintenancePeriod::collect($response->json('data')); + } +} diff --git a/src/Requests/RecurringMaintenancePeriods/UpdateRecurringMaintenancePeriodRequest.php b/src/Requests/RecurringMaintenancePeriods/UpdateRecurringMaintenancePeriodRequest.php new file mode 100644 index 0000000..7ddf64b --- /dev/null +++ b/src/Requests/RecurringMaintenancePeriods/UpdateRecurringMaintenancePeriodRequest.php @@ -0,0 +1,37 @@ +recurringMaintenancePeriodId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): RecurringMaintenancePeriod + { + return RecurringMaintenancePeriod::fromResponse($response->json()); + } +} diff --git a/src/Requests/StatusPages/AddStatusPageMonitorsRequest.php b/src/Requests/StatusPages/AddStatusPageMonitorsRequest.php new file mode 100644 index 0000000..81bd93e --- /dev/null +++ b/src/Requests/StatusPages/AddStatusPageMonitorsRequest.php @@ -0,0 +1,37 @@ +statusPageId}/monitors"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): StatusPage + { + return StatusPage::fromResponse($response->json()); + } +} diff --git a/src/Requests/StatusPages/CreateStatusPageRequest.php b/src/Requests/StatusPages/CreateStatusPageRequest.php new file mode 100644 index 0000000..fae154e --- /dev/null +++ b/src/Requests/StatusPages/CreateStatusPageRequest.php @@ -0,0 +1,36 @@ +data; + } + + public function createDtoFromResponse(Response $response): StatusPage + { + return StatusPage::fromResponse($response->json()); + } +} diff --git a/src/Requests/StatusPages/CreateStatusPageUpdateTemplateRequest.php b/src/Requests/StatusPages/CreateStatusPageUpdateTemplateRequest.php new file mode 100644 index 0000000..8684131 --- /dev/null +++ b/src/Requests/StatusPages/CreateStatusPageUpdateTemplateRequest.php @@ -0,0 +1,36 @@ +data; + } + + public function createDtoFromResponse(Response $response): StatusPageUpdateTemplate + { + return StatusPageUpdateTemplate::fromResponse($response->json()); + } +} diff --git a/src/Requests/StatusPages/DeleteStatusPageMonitorRequest.php b/src/Requests/StatusPages/DeleteStatusPageMonitorRequest.php new file mode 100644 index 0000000..6b96865 --- /dev/null +++ b/src/Requests/StatusPages/DeleteStatusPageMonitorRequest.php @@ -0,0 +1,21 @@ +statusPageId}/monitors/{$this->monitorId}"; + } +} diff --git a/src/Requests/StatusPages/DeleteStatusPageUpdateTemplateRequest.php b/src/Requests/StatusPages/DeleteStatusPageUpdateTemplateRequest.php new file mode 100644 index 0000000..05a0de0 --- /dev/null +++ b/src/Requests/StatusPages/DeleteStatusPageUpdateTemplateRequest.php @@ -0,0 +1,20 @@ +templateId}"; + } +} diff --git a/src/Requests/StatusPages/GetStatusPageUpdateTemplatesRequest.php b/src/Requests/StatusPages/GetStatusPageUpdateTemplatesRequest.php new file mode 100644 index 0000000..88917e7 --- /dev/null +++ b/src/Requests/StatusPages/GetStatusPageUpdateTemplatesRequest.php @@ -0,0 +1,23 @@ +json('data')); + } +} diff --git a/src/Requests/StatusPages/GetStatusPageUpdatesRequest.php b/src/Requests/StatusPages/GetStatusPageUpdatesRequest.php new file mode 100644 index 0000000..7e9896d --- /dev/null +++ b/src/Requests/StatusPages/GetStatusPageUpdatesRequest.php @@ -0,0 +1,30 @@ +statusPageId}/updates"; + } + + public function createDtoFromResponse(Response $response): array + { + return array_map( + fn (array $item) => StatusPageUpdate::fromResponse($item), + $response->json('data') + ); + } +} diff --git a/src/Requests/StatusPages/UpdateStatusPageUpdateRequest.php b/src/Requests/StatusPages/UpdateStatusPageUpdateRequest.php new file mode 100644 index 0000000..e6ab928 --- /dev/null +++ b/src/Requests/StatusPages/UpdateStatusPageUpdateRequest.php @@ -0,0 +1,37 @@ +statusPageUpdateId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): StatusPageUpdate + { + return StatusPageUpdate::fromResponse($response->json()); + } +} diff --git a/src/Requests/StatusPages/UpdateStatusPageUpdateTemplateRequest.php b/src/Requests/StatusPages/UpdateStatusPageUpdateTemplateRequest.php new file mode 100644 index 0000000..66e3dc8 --- /dev/null +++ b/src/Requests/StatusPages/UpdateStatusPageUpdateTemplateRequest.php @@ -0,0 +1,37 @@ +templateId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): StatusPageUpdateTemplate + { + return StatusPageUpdateTemplate::fromResponse($response->json()); + } +} diff --git a/src/Requests/TagGroups/CreateTagGroupRequest.php b/src/Requests/TagGroups/CreateTagGroupRequest.php new file mode 100644 index 0000000..d837c53 --- /dev/null +++ b/src/Requests/TagGroups/CreateTagGroupRequest.php @@ -0,0 +1,36 @@ +data; + } + + public function createDtoFromResponse(Response $response): TagGroup + { + return TagGroup::fromResponse($response->json()); + } +} diff --git a/src/Requests/TagGroups/DeleteTagGroupRequest.php b/src/Requests/TagGroups/DeleteTagGroupRequest.php new file mode 100644 index 0000000..1c6a23d --- /dev/null +++ b/src/Requests/TagGroups/DeleteTagGroupRequest.php @@ -0,0 +1,20 @@ +tagGroupId}"; + } +} diff --git a/src/Requests/TagGroups/GetTagGroupsRequest.php b/src/Requests/TagGroups/GetTagGroupsRequest.php new file mode 100644 index 0000000..b36445a --- /dev/null +++ b/src/Requests/TagGroups/GetTagGroupsRequest.php @@ -0,0 +1,23 @@ +json('data')); + } +} diff --git a/src/Requests/TagGroups/UpdateTagGroupRequest.php b/src/Requests/TagGroups/UpdateTagGroupRequest.php new file mode 100644 index 0000000..f9308db --- /dev/null +++ b/src/Requests/TagGroups/UpdateTagGroupRequest.php @@ -0,0 +1,37 @@ +tagGroupId}"; + } + + protected function defaultBody(): array + { + return $this->data; + } + + public function createDtoFromResponse(Response $response): TagGroup + { + return TagGroup::fromResponse($response->json()); + } +} diff --git a/src/Requests/Tags/CreateTagRequest.php b/src/Requests/Tags/CreateTagRequest.php new file mode 100644 index 0000000..60bac99 --- /dev/null +++ b/src/Requests/Tags/CreateTagRequest.php @@ -0,0 +1,36 @@ +data; + } + + public function createDtoFromResponse(Response $response): Tag + { + return Tag::fromResponse($response->json()); + } +} diff --git a/src/Requests/Tags/GetTagsRequest.php b/src/Requests/Tags/GetTagsRequest.php new file mode 100644 index 0000000..0dcf08a --- /dev/null +++ b/src/Requests/Tags/GetTagsRequest.php @@ -0,0 +1,23 @@ +json('data')); + } +} diff --git a/tests/Fixtures/Saloon/add-status-page-monitors.json b/tests/Fixtures/Saloon/add-status-page-monitors.json new file mode 100644 index 0000000..4851ad9 --- /dev/null +++ b/tests/Fixtures/Saloon/add-status-page-monitors.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":9338,\"team\":{\"id\":19245},\"title\":\"First status page\",\"domain\":null,\"secret\":null,\"badge_id\":null,\"slug\":\"first-status-page\",\"full_url\":\"https://status.example.com\",\"timezone\":\"UTC\",\"summarized_status\":\"up\",\"updates\":[],\"monitors\":[{\"id\":82060}],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/add-to-broken-links-whitelist.json b/tests/Fixtures/Saloon/add-to-broken-links-whitelist.json new file mode 100644 index 0000000..6ee6354 --- /dev/null +++ b/tests/Fixtures/Saloon/add-to-broken-links-whitelist.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{}","context":[]} diff --git a/tests/Fixtures/Saloon/ai-response.json b/tests/Fixtures/Saloon/ai-response.json new file mode 100644 index 0000000..d342962 --- /dev/null +++ b/tests/Fixtures/Saloon/ai-response.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"result\":\"ok\",\"finish_reason\":\"stop\",\"prompt\":\"Check if the site is accessible\",\"text\":\"The site is accessible and responding normally.\",\"notification_title\":null,\"notification_body\":null,\"used_tools\":[],\"used_prompt_tokens\":100,\"used_completion_tokens\":50,\"raw_response\":\"{\\\"message\\\": \\\"All good\\\"}\",\"started_at\":\"2025-01-01 00:00:00\",\"ended_at\":\"2025-01-01 00:00:05\",\"created_at\":\"2025-01-01 00:00:05\"}","context":[]} diff --git a/tests/Fixtures/Saloon/ai-responses.json b/tests/Fixtures/Saloon/ai-responses.json new file mode 100644 index 0000000..8c64e7b --- /dev/null +++ b/tests/Fixtures/Saloon/ai-responses.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"result\":\"ok\",\"finish_reason\":\"stop\",\"prompt\":\"Check if the site is accessible\",\"text\":\"The site is accessible and responding normally.\",\"notification_title\":null,\"notification_body\":null,\"used_tools\":[{\"name\":\"http_check\",\"arguments\":{},\"displayName\":\"HTTP Check\",\"displayArguments\":[]}],\"used_prompt_tokens\":100,\"used_completion_tokens\":50,\"started_at\":\"2025-01-01 00:00:00\",\"ended_at\":\"2025-01-01 00:00:05\",\"created_at\":\"2025-01-01 00:00:05\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/create-recurring-maintenance-period.json b/tests/Fixtures/Saloon/create-recurring-maintenance-period.json new file mode 100644 index 0000000..5bc5186 --- /dev/null +++ b/tests/Fixtures/Saloon/create-recurring-maintenance-period.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":2,\"monitor_id\":82060,\"name\":\"Daily Maintenance\",\"recurrence_type\":\"daily\",\"start_time\":\"03:00\",\"end_time\":\"05:00\",\"days_of_week\":[],\"day_of_month\":null,\"human_readable_schedule\":\"Every day from 03:00 to 05:00\",\"last_generated_until\":\"2025-02-01\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/create-status-page-update-template.json b/tests/Fixtures/Saloon/create-status-page-update-template.json new file mode 100644 index 0000000..ee801d5 --- /dev/null +++ b/tests/Fixtures/Saloon/create-status-page-update-template.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":2,\"team_id\":19245,\"name\":\"Incident Template\",\"title\":\"Service Incident\",\"text\":\"We are investigating an issue.\",\"severity\":\"high\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/create-status-page.json b/tests/Fixtures/Saloon/create-status-page.json new file mode 100644 index 0000000..718de69 --- /dev/null +++ b/tests/Fixtures/Saloon/create-status-page.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":9339,\"team\":{\"id\":19245},\"title\":\"New Status Page\",\"domain\":null,\"secret\":null,\"badge_id\":null,\"slug\":\"new-status-page\",\"full_url\":\"https://status.example.com\",\"timezone\":\"UTC\",\"summarized_status\":\"up\",\"updates\":[],\"monitors\":[],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/create-tag-group-notification-destination.json b/tests/Fixtures/Saloon/create-tag-group-notification-destination.json new file mode 100644 index 0000000..5f8b6d1 --- /dev/null +++ b/tests/Fixtures/Saloon/create-tag-group-notification-destination.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":301,\"label\":null,\"channel\":\"mail\",\"destination\":{\"mail\":\"taggroup@example.com\"},\"notification_types\":[]}","context":[]} diff --git a/tests/Fixtures/Saloon/create-tag-group.json b/tests/Fixtures/Saloon/create-tag-group.json new file mode 100644 index 0000000..80a3c74 --- /dev/null +++ b/tests/Fixtures/Saloon/create-tag-group.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":2,\"team_id\":19245,\"team_name\":\"Oh Dear\",\"label\":\"Region\",\"tags\":[],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/create-tag-notification-destination.json b/tests/Fixtures/Saloon/create-tag-notification-destination.json new file mode 100644 index 0000000..c01275c --- /dev/null +++ b/tests/Fixtures/Saloon/create-tag-notification-destination.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":201,\"label\":null,\"channel\":\"mail\",\"destination\":{\"mail\":\"newtag@example.com\"},\"notification_types\":[]}","context":[]} diff --git a/tests/Fixtures/Saloon/create-tag.json b/tests/Fixtures/Saloon/create-tag.json new file mode 100644 index 0000000..34cdf43 --- /dev/null +++ b/tests/Fixtures/Saloon/create-tag.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":2,\"team_id\":19245,\"team_name\":\"Oh Dear\",\"name\":\"staging\",\"slug\":\"staging\",\"sites\":[],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/create-team-notification-destination.json b/tests/Fixtures/Saloon/create-team-notification-destination.json new file mode 100644 index 0000000..96942fa --- /dev/null +++ b/tests/Fixtures/Saloon/create-team-notification-destination.json @@ -0,0 +1 @@ +{"statusCode":201,"headers":{"Content-Type":"application/json"},"data":"{\"id\":101,\"label\":null,\"channel\":\"mail\",\"destination\":{\"mail\":\"team@example.com\"},\"notification_types\":[]}","context":[]} diff --git a/tests/Fixtures/Saloon/delete-notification-destination.json b/tests/Fixtures/Saloon/delete-notification-destination.json new file mode 100644 index 0000000..2c5dce8 --- /dev/null +++ b/tests/Fixtures/Saloon/delete-notification-destination.json @@ -0,0 +1 @@ +{"statusCode":204,"headers":{},"data":"","context":[]} diff --git a/tests/Fixtures/Saloon/delete-recurring-maintenance-period.json b/tests/Fixtures/Saloon/delete-recurring-maintenance-period.json new file mode 100644 index 0000000..2c5dce8 --- /dev/null +++ b/tests/Fixtures/Saloon/delete-recurring-maintenance-period.json @@ -0,0 +1 @@ +{"statusCode":204,"headers":{},"data":"","context":[]} diff --git a/tests/Fixtures/Saloon/delete-status-page-monitor.json b/tests/Fixtures/Saloon/delete-status-page-monitor.json new file mode 100644 index 0000000..2c5dce8 --- /dev/null +++ b/tests/Fixtures/Saloon/delete-status-page-monitor.json @@ -0,0 +1 @@ +{"statusCode":204,"headers":{},"data":"","context":[]} diff --git a/tests/Fixtures/Saloon/delete-status-page-update-template.json b/tests/Fixtures/Saloon/delete-status-page-update-template.json new file mode 100644 index 0000000..2c5dce8 --- /dev/null +++ b/tests/Fixtures/Saloon/delete-status-page-update-template.json @@ -0,0 +1 @@ +{"statusCode":204,"headers":{},"data":"","context":[]} diff --git a/tests/Fixtures/Saloon/delete-tag-group.json b/tests/Fixtures/Saloon/delete-tag-group.json new file mode 100644 index 0000000..2c5dce8 --- /dev/null +++ b/tests/Fixtures/Saloon/delete-tag-group.json @@ -0,0 +1 @@ +{"statusCode":204,"headers":{},"data":"","context":[]} diff --git a/tests/Fixtures/Saloon/dns-blocklist-history-item.json b/tests/Fixtures/Saloon/dns-blocklist-history-item.json new file mode 100644 index 0000000..437b1d3 --- /dev/null +++ b/tests/Fixtures/Saloon/dns-blocklist-history-item.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"checked_domain\":\"example.com\",\"resolved_ips\":[\"93.184.216.34\"],\"blocklist_results\":[{\"provider\":\"zen.spamhaus.org\",\"listed\":false,\"query_target\":null,\"return_code\":null,\"reason\":null,\"timed_out\":false}],\"issues\":null,\"created_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/dns-blocklist-history-items.json b/tests/Fixtures/Saloon/dns-blocklist-history-items.json new file mode 100644 index 0000000..361d4f7 --- /dev/null +++ b/tests/Fixtures/Saloon/dns-blocklist-history-items.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"checked_domain\":\"example.com\",\"resolved_ips\":[\"93.184.216.34\"],\"blocklist_results\":[{\"provider\":\"zen.spamhaus.org\",\"listed\":false,\"query_target\":null,\"return_code\":null,\"reason\":null,\"timed_out\":false}],\"issues\":null,\"created_at\":\"2025-01-01 00:00:00\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/domain.json b/tests/Fixtures/Saloon/domain.json new file mode 100644 index 0000000..155b22d --- /dev/null +++ b/tests/Fixtures/Saloon/domain.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"expires_at\":\"2026-01-01 00:00:00\",\"registered_at\":\"2020-01-01 00:00:00\",\"last_changed_at\":\"2024-06-01 00:00:00\",\"last_updated_in_rdap_db_at\":\"2025-01-01 00:00:00\",\"domain_statuses\":[\"clientTransferProhibited\"],\"rdap_domain_response\":{},\"created_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/latest-ai-response.json b/tests/Fixtures/Saloon/latest-ai-response.json new file mode 100644 index 0000000..d342962 --- /dev/null +++ b/tests/Fixtures/Saloon/latest-ai-response.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"result\":\"ok\",\"finish_reason\":\"stop\",\"prompt\":\"Check if the site is accessible\",\"text\":\"The site is accessible and responding normally.\",\"notification_title\":null,\"notification_body\":null,\"used_tools\":[],\"used_prompt_tokens\":100,\"used_completion_tokens\":50,\"raw_response\":\"{\\\"message\\\": \\\"All good\\\"}\",\"started_at\":\"2025-01-01 00:00:00\",\"ended_at\":\"2025-01-01 00:00:05\",\"created_at\":\"2025-01-01 00:00:05\"}","context":[]} diff --git a/tests/Fixtures/Saloon/monitor-by-url.json b/tests/Fixtures/Saloon/monitor-by-url.json new file mode 100644 index 0000000..5a48dea --- /dev/null +++ b/tests/Fixtures/Saloon/monitor-by-url.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":82063,\"team_id\":19245,\"type\":\"http\",\"url\":\"https://laravel.com\",\"uses_https\":true,\"sort_url\":\"laravel.com\",\"label\":\"laravel.com\",\"group_name\":\"\",\"tags\":[],\"description\":null,\"notes\":null,\"latest_run_date\":null,\"summarized_check_result\":\"succeeded\",\"checks\":[],\"uptime_check_settings\":{},\"certificate_health_check_settings\":{},\"broken_links_check_settings\":{},\"dns_check_settings\":{},\"lighthouse_check_settings\":{},\"application_health_check_settings\":{},\"domain_check_settings\":{},\"performance_check_settings\":{},\"sitemap_check_settings\":{},\"crawler_headers\":[],\"send_report_to_emails\":[],\"include_check_types_in_report\":[],\"badge_id\":null,\"marked_for_deletion_at\":null,\"created_at\":\"2025-08-08 14:13:52\",\"updated_at\":\"2025-08-08 14:41:01\"}","context":[]} diff --git a/tests/Fixtures/Saloon/ports-history-item.json b/tests/Fixtures/Saloon/ports-history-item.json new file mode 100644 index 0000000..609d0eb --- /dev/null +++ b/tests/Fixtures/Saloon/ports-history-item.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"scanned_host\":\"example.com\",\"expected_open_results\":[{\"port\":80,\"status\":\"open\"}],\"expected_closed_results\":[{\"port\":23,\"status\":\"closed\"}],\"issues\":[],\"scan_time_ms\":1500,\"created_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/ports-history-items.json b/tests/Fixtures/Saloon/ports-history-items.json new file mode 100644 index 0000000..ba2af1a --- /dev/null +++ b/tests/Fixtures/Saloon/ports-history-items.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"scanned_host\":\"example.com\",\"expected_open_results\":[{\"port\":80,\"status\":\"open\"}],\"expected_closed_results\":[{\"port\":23,\"status\":\"closed\"}],\"issues\":[],\"scan_time_ms\":1500,\"created_at\":\"2025-01-01 00:00:00\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/recurring-maintenance-period.json b/tests/Fixtures/Saloon/recurring-maintenance-period.json new file mode 100644 index 0000000..b28941b --- /dev/null +++ b/tests/Fixtures/Saloon/recurring-maintenance-period.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"monitor_id\":82060,\"name\":\"Weekly Maintenance\",\"recurrence_type\":\"weekly\",\"start_time\":\"02:00\",\"end_time\":\"04:00\",\"days_of_week\":[1,3,5],\"day_of_month\":null,\"human_readable_schedule\":\"Every Monday, Wednesday and Friday from 02:00 to 04:00\",\"last_generated_until\":\"2025-02-01\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/recurring-maintenance-periods.json b/tests/Fixtures/Saloon/recurring-maintenance-periods.json new file mode 100644 index 0000000..222eb3b --- /dev/null +++ b/tests/Fixtures/Saloon/recurring-maintenance-periods.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"monitor_id\":82060,\"name\":\"Weekly Maintenance\",\"recurrence_type\":\"weekly\",\"start_time\":\"02:00\",\"end_time\":\"04:00\",\"days_of_week\":[1,3,5],\"day_of_month\":null,\"human_readable_schedule\":\"Every Monday, Wednesday and Friday from 02:00 to 04:00\",\"last_generated_until\":\"2025-02-01\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/snooze-application-health-check.json b/tests/Fixtures/Saloon/snooze-application-health-check.json new file mode 100644 index 0000000..6efb318 --- /dev/null +++ b/tests/Fixtures/Saloon/snooze-application-health-check.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":2608325,\"name\":\"Database\",\"label\":\"Database\",\"status\":\"ok\",\"message\":\"Connected\",\"meta\":[],\"short_summary\":\"OK\",\"detected_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\",\"active_snooze\":{\"minutes\":60}}","context":[]} diff --git a/tests/Fixtures/Saloon/status-page-update-templates.json b/tests/Fixtures/Saloon/status-page-update-templates.json new file mode 100644 index 0000000..625bbc0 --- /dev/null +++ b/tests/Fixtures/Saloon/status-page-update-templates.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"team_id\":19245,\"name\":\"Maintenance Template\",\"title\":\"Scheduled Maintenance\",\"text\":\"We are performing scheduled maintenance.\",\"severity\":\"info\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/status-page-updates.json b/tests/Fixtures/Saloon/status-page-updates.json new file mode 100644 index 0000000..d2d0144 --- /dev/null +++ b/tests/Fixtures/Saloon/status-page-updates.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1234,\"title\":\"Our site is down\",\"text\":\"We are working on it!\",\"pinned\":true,\"severity\":\"high\",\"time\":\"2025-01-01 00:00:00\",\"status_page_url\":\"https://status.example.com\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/sync-cron-check-definitions.json b/tests/Fixtures/Saloon/sync-cron-check-definitions.json new file mode 100644 index 0000000..688b72f --- /dev/null +++ b/tests/Fixtures/Saloon/sync-cron-check-definitions.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":208283,\"uuid\":\"abc-123\",\"name\":\"Sync Test\",\"type\":\"simple\",\"description\":null,\"frequency_in_minutes\":60,\"grace_time_in_minutes\":10,\"cron_expression\":null,\"human_readable_cron_expression\":\"\",\"server_timezone\":null,\"ping_url\":\"https://ping.ohdear.app/abc-123\",\"created_at\":\"2025-01-01 00:00:00\",\"latest_result\":\"\",\"latest_result_label\":\"\",\"latest_result_label_color\":\"\",\"latest_ping_at\":null,\"human_readable_latest_ping_at\":\"\",\"active_snooze\":null}]}","context":[]} diff --git a/tests/Fixtures/Saloon/tag-group-notification-destinations.json b/tests/Fixtures/Saloon/tag-group-notification-destinations.json new file mode 100644 index 0000000..79a0a89 --- /dev/null +++ b/tests/Fixtures/Saloon/tag-group-notification-destinations.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":300,\"label\":\"TagGroup Slack\",\"channel\":\"slack\",\"destination\":{\"webhook_url\":\"https://hooks.slack.com/tg\"},\"notification_types\":[]}]}","context":[]} diff --git a/tests/Fixtures/Saloon/tag-groups.json b/tests/Fixtures/Saloon/tag-groups.json new file mode 100644 index 0000000..627590f --- /dev/null +++ b/tests/Fixtures/Saloon/tag-groups.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"team_id\":19245,\"team_name\":\"Oh Dear\",\"label\":\"Environment\",\"tags\":[],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/tag-notification-destinations.json b/tests/Fixtures/Saloon/tag-notification-destinations.json new file mode 100644 index 0000000..b76f11c --- /dev/null +++ b/tests/Fixtures/Saloon/tag-notification-destinations.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":200,\"label\":\"Tag Email\",\"channel\":\"mail\",\"destination\":{\"mail\":\"tag@example.com\"},\"notification_types\":[]}]}","context":[]} diff --git a/tests/Fixtures/Saloon/tags.json b/tests/Fixtures/Saloon/tags.json new file mode 100644 index 0000000..5f5b1cf --- /dev/null +++ b/tests/Fixtures/Saloon/tags.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":1,\"team_id\":19245,\"team_name\":\"Oh Dear\",\"name\":\"production\",\"slug\":\"production\",\"sites\":[],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\"}]}","context":[]} diff --git a/tests/Fixtures/Saloon/team-notification-destinations.json b/tests/Fixtures/Saloon/team-notification-destinations.json new file mode 100644 index 0000000..e938e2e --- /dev/null +++ b/tests/Fixtures/Saloon/team-notification-destinations.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"data\":[{\"id\":100,\"label\":\"Team Slack\",\"channel\":\"slack\",\"destination\":{\"webhook_url\":\"https://hooks.slack.com/test\"},\"notification_types\":[]}]}","context":[]} diff --git a/tests/Fixtures/Saloon/unsnooze-application-health-check.json b/tests/Fixtures/Saloon/unsnooze-application-health-check.json new file mode 100644 index 0000000..97f56d8 --- /dev/null +++ b/tests/Fixtures/Saloon/unsnooze-application-health-check.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":2608325,\"name\":\"Database\",\"label\":\"Database\",\"status\":\"ok\",\"message\":\"Connected\",\"meta\":[],\"short_summary\":\"OK\",\"detected_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-01 00:00:00\",\"active_snooze\":null}","context":[]} diff --git a/tests/Fixtures/Saloon/update-notification-destination.json b/tests/Fixtures/Saloon/update-notification-destination.json new file mode 100644 index 0000000..3bcaecf --- /dev/null +++ b/tests/Fixtures/Saloon/update-notification-destination.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":456,\"label\":\"Updated\",\"channel\":\"mail\",\"destination\":{\"mail\":\"updated@example.com\"},\"notification_types\":[]}","context":[]} diff --git a/tests/Fixtures/Saloon/update-recurring-maintenance-period.json b/tests/Fixtures/Saloon/update-recurring-maintenance-period.json new file mode 100644 index 0000000..09c6f28 --- /dev/null +++ b/tests/Fixtures/Saloon/update-recurring-maintenance-period.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"monitor_id\":82060,\"name\":\"Updated Maintenance\",\"recurrence_type\":\"weekly\",\"start_time\":\"01:00\",\"end_time\":\"03:00\",\"days_of_week\":[1,2,3,4,5],\"day_of_month\":null,\"human_readable_schedule\":\"Every weekday from 01:00 to 03:00\",\"last_generated_until\":\"2025-02-01\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-02 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/update-status-page-update-template.json b/tests/Fixtures/Saloon/update-status-page-update-template.json new file mode 100644 index 0000000..6d9d142 --- /dev/null +++ b/tests/Fixtures/Saloon/update-status-page-update-template.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"team_id\":19245,\"name\":\"Updated Template\",\"title\":\"Updated Title\",\"text\":\"Updated text.\",\"severity\":\"warning\",\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-02 00:00:00\"}","context":[]} diff --git a/tests/Fixtures/Saloon/update-status-page-update.json b/tests/Fixtures/Saloon/update-status-page-update.json new file mode 100644 index 0000000..221d552 --- /dev/null +++ b/tests/Fixtures/Saloon/update-status-page-update.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1234,\"title\":\"Updated title\",\"text\":\"Updated text\",\"pinned\":false,\"severity\":\"info\",\"time\":\"2025-01-01 00:00:00\",\"status_page_url\":\"https://status.example.com\"}","context":[]} diff --git a/tests/Fixtures/Saloon/update-tag-group.json b/tests/Fixtures/Saloon/update-tag-group.json new file mode 100644 index 0000000..daa42fa --- /dev/null +++ b/tests/Fixtures/Saloon/update-tag-group.json @@ -0,0 +1 @@ +{"statusCode":200,"headers":{"Content-Type":"application/json"},"data":"{\"id\":1,\"team_id\":19245,\"team_name\":\"Oh Dear\",\"label\":\"Updated Environment\",\"tags\":[],\"created_at\":\"2025-01-01 00:00:00\",\"updated_at\":\"2025-01-02 00:00:00\"}","context":[]} diff --git a/tests/OhDearTests/AiResponsesTest.php b/tests/OhDearTests/AiResponsesTest.php new file mode 100644 index 0000000..58da90c --- /dev/null +++ b/tests/OhDearTests/AiResponsesTest.php @@ -0,0 +1,52 @@ +ohDear = ohDearMock(); +}); + +it('can get ai responses', function () { + MockClient::global([ + GetAiResponsesRequest::class => MockResponse::fixture('ai-responses'), + ]); + + $responses = $this->ohDear->aiResponses(82060); + + expect($responses)->toBeArray(); + foreach ($responses as $response) { + expect($response->id)->toBeInt(); + expect($response->result)->toBe('ok'); + expect($response->text)->toBeString(); + } +}); + +it('can get a single ai response', function () { + MockClient::global([ + GetAiResponseRequest::class => MockResponse::fixture('ai-response'), + ]); + + $response = $this->ohDear->aiResponse(82060, 1); + + expect($response->id)->toBe(1); + expect($response->result)->toBe('ok'); + expect($response->finishReason)->toBe('stop'); + expect($response->prompt)->toBeString(); + expect($response->text)->toBeString(); +}); + +it('can get the latest ai response', function () { + MockClient::global([ + GetLatestAiResponseRequest::class => MockResponse::fixture('latest-ai-response'), + ]); + + $response = $this->ohDear->latestAiResponse(82060); + + expect($response->id)->toBe(1); + expect($response->result)->toBe('ok'); + expect($response->rawResponse)->toBeString(); +}); diff --git a/tests/OhDearTests/ApplicationHealthChecksTest.php b/tests/OhDearTests/ApplicationHealthChecksTest.php index b5a1df5..bb40765 100644 --- a/tests/OhDearTests/ApplicationHealthChecksTest.php +++ b/tests/OhDearTests/ApplicationHealthChecksTest.php @@ -2,6 +2,8 @@ use OhDear\PhpSdk\Requests\ApplicationHealthChecks\GetApplicationHealthCheckHistoryRequest; use OhDear\PhpSdk\Requests\ApplicationHealthChecks\GetApplicationHealthChecksRequest; +use OhDear\PhpSdk\Requests\ApplicationHealthChecks\SnoozeApplicationHealthCheckRequest; +use OhDear\PhpSdk\Requests\ApplicationHealthChecks\UnsnoozeApplicationHealthCheckRequest; use Saloon\Http\Faking\MockClient; use Saloon\Http\Faking\MockResponse; @@ -46,3 +48,27 @@ expect($historyItem->updatedAt)->toBeString(); } }); + +it('can snooze an application health check', function () { + MockClient::global([ + SnoozeApplicationHealthCheckRequest::class => MockResponse::fixture('snooze-application-health-check'), + ]); + + $healthCheck = $this->ohDear->snoozeApplicationHealthCheck(82060, 2608325, 60); + + expect($healthCheck->id)->toBe(2608325); + expect($healthCheck->name)->toBe('Database'); + expect($healthCheck->activeSnooze)->toBeArray(); +}); + +it('can unsnooze an application health check', function () { + MockClient::global([ + UnsnoozeApplicationHealthCheckRequest::class => MockResponse::fixture('unsnooze-application-health-check'), + ]); + + $healthCheck = $this->ohDear->unsnoozeApplicationHealthCheck(82060, 2608325); + + expect($healthCheck->id)->toBe(2608325); + expect($healthCheck->name)->toBe('Database'); + expect($healthCheck->activeSnooze)->toBeNull(); +}); diff --git a/tests/OhDearTests/CronCheckDefinitionsTest.php b/tests/OhDearTests/CronCheckDefinitionsTest.php index 58e9cb1..ba2e9db 100644 --- a/tests/OhDearTests/CronCheckDefinitionsTest.php +++ b/tests/OhDearTests/CronCheckDefinitionsTest.php @@ -5,6 +5,7 @@ use OhDear\PhpSdk\Requests\CronCheckDefinitions\DeleteCronCheckDefinitionRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\GetCronCheckDefinitionsRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\SnoozeCronCheckDefinitionRequest; +use OhDear\PhpSdk\Requests\CronCheckDefinitions\SyncCronCheckDefinitionsRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\UnsnoozeCronCheckDefinitionRequest; use OhDear\PhpSdk\Requests\CronCheckDefinitions\UpdateCronCheckDefinitionRequest; use Saloon\Http\Faking\MockClient; @@ -102,3 +103,19 @@ expect($cronCheckDefinition->id)->toBeInt(); expect($cronCheckDefinition->name)->toBeString(); }); + +it('can sync cron check definitions', function () { + MockClient::global([ + SyncCronCheckDefinitionsRequest::class => MockResponse::fixture('sync-cron-check-definitions'), + ]); + + $cronCheckDefinitions = $this->ohDear->syncCronCheckDefinitions(82060, [ + ['name' => 'Sync Test', 'type' => 'simple', 'frequency_in_minutes' => 60], + ]); + + expect($cronCheckDefinitions)->toBeArray(); + foreach ($cronCheckDefinitions as $cronCheckDefinition) { + expect($cronCheckDefinition->id)->toBeInt(); + expect($cronCheckDefinition->name)->toBeString(); + } +}); diff --git a/tests/OhDearTests/DnsBlocklistHistoryItemsTest.php b/tests/OhDearTests/DnsBlocklistHistoryItemsTest.php new file mode 100644 index 0000000..6fa600f --- /dev/null +++ b/tests/OhDearTests/DnsBlocklistHistoryItemsTest.php @@ -0,0 +1,37 @@ +ohDear = ohDearMock(); +}); + +it('can get dns blocklist history items', function () { + MockClient::global([ + GetDnsBlocklistHistoryItemsRequest::class => MockResponse::fixture('dns-blocklist-history-items'), + ]); + + $items = $this->ohDear->dnsBlocklistHistoryItems(82060); + + expect($items)->toBeArray(); + foreach ($items as $item) { + expect($item->id)->toBeInt(); + expect($item->checkedDomain)->toBeString(); + } +}); + +it('can get a single dns blocklist history item', function () { + MockClient::global([ + GetDnsBlocklistHistoryItemRequest::class => MockResponse::fixture('dns-blocklist-history-item'), + ]); + + $item = $this->ohDear->dnsBlocklistHistoryItem(82060, 1); + + expect($item->id)->toBe(1); + expect($item->checkedDomain)->toBe('example.com'); + expect($item->resolvedIps)->toBeArray(); + expect($item->blocklistResults)->toBeArray(); +}); diff --git a/tests/OhDearTests/DomainTest.php b/tests/OhDearTests/DomainTest.php new file mode 100644 index 0000000..6557e35 --- /dev/null +++ b/tests/OhDearTests/DomainTest.php @@ -0,0 +1,21 @@ +ohDear = ohDearMock(); +}); + +it('can get domain info for a monitor', function () { + MockClient::global([ + GetDomainRequest::class => MockResponse::fixture('domain'), + ]); + + $domain = $this->ohDear->domain(82060); + + expect($domain->expiresAt)->toBe('2026-01-01 00:00:00'); + expect($domain->registeredAt)->toBe('2020-01-01 00:00:00'); + expect($domain->domainStatuses)->toBeArray(); +}); diff --git a/tests/OhDearTests/MonitorsTest.php b/tests/OhDearTests/MonitorsTest.php index 82fb06e..10021c0 100644 --- a/tests/OhDearTests/MonitorsTest.php +++ b/tests/OhDearTests/MonitorsTest.php @@ -1,10 +1,12 @@ channel)->toBe('mail'); expect($notificationDestination->destination['mail'])->toBe('example@example.com'); }); + +it('can get a monitor by url', function () { + MockClient::global([ + GetMonitorByUrlRequest::class => MockResponse::fixture('monitor-by-url'), + ]); + + $monitor = $this->ohDear->monitorByUrl('https://laravel.com'); + + expect($monitor->id)->toBe(82063); + expect($monitor->url)->toBe('https://laravel.com'); +}); + +it('can add a url to broken links whitelist', function () { + MockClient::global([ + AddToBrokenLinksWhitelistRequest::class => MockResponse::fixture('add-to-broken-links-whitelist'), + ]); + + $this->ohDear->addToBrokenLinksWhitelist(82060, 'https://example.com/skip'); + + markTestComplete(); +}); diff --git a/tests/OhDearTests/NotificationDestinationsTest.php b/tests/OhDearTests/NotificationDestinationsTest.php new file mode 100644 index 0000000..725311d --- /dev/null +++ b/tests/OhDearTests/NotificationDestinationsTest.php @@ -0,0 +1,121 @@ +ohDear = ohDearMock(); +}); + +it('can update a monitor notification destination', function () { + MockClient::global([ + UpdateNotificationDestinationRequest::class => MockResponse::fixture('update-notification-destination'), + ]); + + $destination = $this->ohDear->updateNotificationDestination(82060, 456, [ + 'channel' => 'mail', + 'destination' => ['mail' => 'updated@example.com'], + ]); + + expect($destination->id)->toBe(456); + expect($destination->channel)->toBe('mail'); +}); + +it('can delete a monitor notification destination', function () { + MockClient::global([ + DeleteNotificationDestinationRequest::class => MockResponse::fixture('delete-notification-destination'), + ]); + + $this->ohDear->deleteNotificationDestination(82060, 456); + + markTestComplete(); +}); + +it('can get team notification destinations', function () { + MockClient::global([ + GetTeamNotificationDestinationsRequest::class => MockResponse::fixture('team-notification-destinations'), + ]); + + $destinations = $this->ohDear->teamNotificationDestinations(); + + expect($destinations)->toBeArray(); + foreach ($destinations as $destination) { + expect($destination->id)->toBeInt(); + } +}); + +it('can create a team notification destination', function () { + MockClient::global([ + CreateTeamNotificationDestinationRequest::class => MockResponse::fixture('create-team-notification-destination'), + ]); + + $destination = $this->ohDear->createTeamNotificationDestination(19245, [ + 'channel' => 'mail', + 'destination' => ['mail' => 'team@example.com'], + ]); + + expect($destination->id)->toBe(101); + expect($destination->channel)->toBe('mail'); +}); + +it('can get tag notification destinations', function () { + MockClient::global([ + GetTagNotificationDestinationsRequest::class => MockResponse::fixture('tag-notification-destinations'), + ]); + + $destinations = $this->ohDear->tagNotificationDestinations(); + + expect($destinations)->toBeArray(); + foreach ($destinations as $destination) { + expect($destination->id)->toBeInt(); + } +}); + +it('can create a tag notification destination', function () { + MockClient::global([ + CreateTagNotificationDestinationRequest::class => MockResponse::fixture('create-tag-notification-destination'), + ]); + + $destination = $this->ohDear->createTagNotificationDestination(1, [ + 'channel' => 'mail', + 'destination' => ['mail' => 'newtag@example.com'], + ]); + + expect($destination->id)->toBe(201); + expect($destination->channel)->toBe('mail'); +}); + +it('can get tag group notification destinations', function () { + MockClient::global([ + GetTagGroupNotificationDestinationsRequest::class => MockResponse::fixture('tag-group-notification-destinations'), + ]); + + $destinations = $this->ohDear->tagGroupNotificationDestinations(1); + + expect($destinations)->toBeArray(); + foreach ($destinations as $destination) { + expect($destination->id)->toBeInt(); + } +}); + +it('can create a tag group notification destination', function () { + MockClient::global([ + CreateTagGroupNotificationDestinationRequest::class => MockResponse::fixture('create-tag-group-notification-destination'), + ]); + + $destination = $this->ohDear->createTagGroupNotificationDestination(1, [ + 'channel' => 'mail', + 'destination' => ['mail' => 'taggroup@example.com'], + ]); + + expect($destination->id)->toBe(301); + expect($destination->channel)->toBe('mail'); +}); diff --git a/tests/OhDearTests/PortsHistoryItemsTest.php b/tests/OhDearTests/PortsHistoryItemsTest.php new file mode 100644 index 0000000..8ca85b1 --- /dev/null +++ b/tests/OhDearTests/PortsHistoryItemsTest.php @@ -0,0 +1,36 @@ +ohDear = ohDearMock(); +}); + +it('can get ports history items', function () { + MockClient::global([ + GetPortsHistoryItemsRequest::class => MockResponse::fixture('ports-history-items'), + ]); + + $items = $this->ohDear->portsHistoryItems(82060); + + expect($items)->toBeArray(); + foreach ($items as $item) { + expect($item->id)->toBeInt(); + expect($item->scannedHost)->toBeString(); + } +}); + +it('can get a single ports history item', function () { + MockClient::global([ + GetPortsHistoryItemRequest::class => MockResponse::fixture('ports-history-item'), + ]); + + $item = $this->ohDear->portsHistoryItem(82060, 1); + + expect($item->id)->toBe(1); + expect($item->scannedHost)->toBe('example.com'); + expect($item->scanTimeMs)->toBe(1500); +}); diff --git a/tests/OhDearTests/RecurringMaintenancePeriodsTest.php b/tests/OhDearTests/RecurringMaintenancePeriodsTest.php new file mode 100644 index 0000000..fb6c7f9 --- /dev/null +++ b/tests/OhDearTests/RecurringMaintenancePeriodsTest.php @@ -0,0 +1,83 @@ +ohDear = ohDearMock(); +}); + +it('can get recurring maintenance periods', function () { + MockClient::global([ + GetRecurringMaintenancePeriodsRequest::class => MockResponse::fixture('recurring-maintenance-periods'), + ]); + + $periods = $this->ohDear->recurringMaintenancePeriods(82060); + + expect($periods)->toBeArray(); + foreach ($periods as $period) { + expect($period->id)->toBeInt(); + expect($period->monitorId)->toBe(82060); + } +}); + +it('can get a single recurring maintenance period', function () { + MockClient::global([ + GetRecurringMaintenancePeriodRequest::class => MockResponse::fixture('recurring-maintenance-period'), + ]); + + $period = $this->ohDear->recurringMaintenancePeriod(1); + + expect($period->id)->toBe(1); + expect($period->monitorId)->toBe(82060); + expect($period->name)->toBe('Weekly Maintenance'); + expect($period->recurrenceType)->toBe('weekly'); +}); + +it('can create a recurring maintenance period', function () { + MockClient::global([ + CreateRecurringMaintenancePeriodRequest::class => MockResponse::fixture('create-recurring-maintenance-period'), + ]); + + $period = $this->ohDear->createRecurringMaintenancePeriod([ + 'monitor_id' => 82060, + 'name' => 'Daily Maintenance', + 'recurrence_type' => 'daily', + 'start_time' => '03:00', + 'end_time' => '05:00', + ]); + + expect($period->id)->toBe(2); + expect($period->name)->toBe('Daily Maintenance'); + expect($period->recurrenceType)->toBe('daily'); +}); + +it('can update a recurring maintenance period', function () { + MockClient::global([ + UpdateRecurringMaintenancePeriodRequest::class => MockResponse::fixture('update-recurring-maintenance-period'), + ]); + + $period = $this->ohDear->updateRecurringMaintenancePeriod(1, [ + 'name' => 'Updated Maintenance', + 'start_time' => '01:00', + 'end_time' => '03:00', + ]); + + expect($period->id)->toBe(1); + expect($period->name)->toBe('Updated Maintenance'); +}); + +it('can delete a recurring maintenance period', function () { + MockClient::global([ + DeleteRecurringMaintenancePeriodRequest::class => MockResponse::fixture('delete-recurring-maintenance-period'), + ]); + + $this->ohDear->deleteRecurringMaintenancePeriod(1); + + markTestComplete(); +}); diff --git a/tests/OhDearTests/StatusPageUpdateTemplatesTest.php b/tests/OhDearTests/StatusPageUpdateTemplatesTest.php new file mode 100644 index 0000000..758d5b5 --- /dev/null +++ b/tests/OhDearTests/StatusPageUpdateTemplatesTest.php @@ -0,0 +1,66 @@ +ohDear = ohDearMock(); +}); + +it('can get status page update templates', function () { + MockClient::global([ + GetStatusPageUpdateTemplatesRequest::class => MockResponse::fixture('status-page-update-templates'), + ]); + + $templates = $this->ohDear->statusPageUpdateTemplates(); + + expect($templates)->toBeArray(); + foreach ($templates as $template) { + expect($template->id)->toBeInt(); + expect($template->name)->toBeString(); + } +}); + +it('can create a status page update template', function () { + MockClient::global([ + CreateStatusPageUpdateTemplateRequest::class => MockResponse::fixture('create-status-page-update-template'), + ]); + + $template = $this->ohDear->createStatusPageUpdateTemplate([ + 'name' => 'Incident Template', + 'title' => 'Service Incident', + 'text' => 'We are investigating an issue.', + 'severity' => 'high', + ]); + + expect($template->id)->toBe(2); + expect($template->name)->toBe('Incident Template'); + expect($template->severity)->toBe('high'); +}); + +it('can update a status page update template', function () { + MockClient::global([ + UpdateStatusPageUpdateTemplateRequest::class => MockResponse::fixture('update-status-page-update-template'), + ]); + + $template = $this->ohDear->updateStatusPageUpdateTemplate(1, [ + 'name' => 'Updated Template', + ]); + + expect($template->id)->toBe(1); + expect($template->name)->toBe('Updated Template'); +}); + +it('can delete a status page update template', function () { + MockClient::global([ + DeleteStatusPageUpdateTemplateRequest::class => MockResponse::fixture('delete-status-page-update-template'), + ]); + + $this->ohDear->deleteStatusPageUpdateTemplate(1); + + markTestComplete(); +}); diff --git a/tests/OhDearTests/StatusPagesTest.php b/tests/OhDearTests/StatusPagesTest.php index 62305b0..915161a 100644 --- a/tests/OhDearTests/StatusPagesTest.php +++ b/tests/OhDearTests/StatusPagesTest.php @@ -1,10 +1,15 @@ MockResponse::fixture('create-status-page'), + ]); + + $statusPage = $this->ohDear->createStatusPage([ + 'title' => 'New Status Page', + 'team_id' => 19245, + ]); + + expect($statusPage->id)->toBe(9339); + expect($statusPage->title)->toBe('New Status Page'); +}); + +it('can add monitors to a status page', function () { + MockClient::global([ + AddStatusPageMonitorsRequest::class => MockResponse::fixture('add-status-page-monitors'), + ]); + + $statusPage = $this->ohDear->addStatusPageMonitors(9338, [ + 'monitors' => [82060], + ]); + + expect($statusPage->id)->toBe(9338); + expect($statusPage->monitors)->toBeArray(); +}); + +it('can delete a monitor from a status page', function () { + MockClient::global([ + DeleteStatusPageMonitorRequest::class => MockResponse::fixture('delete-status-page-monitor'), + ]); + + $this->ohDear->deleteStatusPageMonitor(9338, 82060); + + markTestComplete(); +}); + +it('can get status page updates', function () { + MockClient::global([ + GetStatusPageUpdatesRequest::class => MockResponse::fixture('status-page-updates'), + ]); + + $updates = $this->ohDear->statusPageUpdates(9338); + + expect($updates)->toBeArray(); + foreach ($updates as $update) { + expect($update->id)->toBeInt(); + expect($update->title)->toBeString(); + } +}); + +it('can update a status page update', function () { + MockClient::global([ + UpdateStatusPageUpdateRequest::class => MockResponse::fixture('update-status-page-update'), + ]); + + $update = $this->ohDear->updateStatusPageUpdate(1234, [ + 'title' => 'Updated title', + 'text' => 'Updated text', + ]); + + expect($update->id)->toBe(1234); + expect($update->title)->toBe('Updated title'); +}); diff --git a/tests/OhDearTests/TagGroupsTest.php b/tests/OhDearTests/TagGroupsTest.php new file mode 100644 index 0000000..9d27299 --- /dev/null +++ b/tests/OhDearTests/TagGroupsTest.php @@ -0,0 +1,63 @@ +ohDear = ohDearMock(); +}); + +it('can get tag groups', function () { + MockClient::global([ + GetTagGroupsRequest::class => MockResponse::fixture('tag-groups'), + ]); + + $tagGroups = $this->ohDear->tagGroups(); + + expect($tagGroups)->toBeArray(); + foreach ($tagGroups as $tagGroup) { + expect($tagGroup->id)->toBeInt(); + expect($tagGroup->label)->toBeString(); + } +}); + +it('can create a tag group', function () { + MockClient::global([ + CreateTagGroupRequest::class => MockResponse::fixture('create-tag-group'), + ]); + + $tagGroup = $this->ohDear->createTagGroup([ + 'label' => 'Region', + 'team_id' => 19245, + ]); + + expect($tagGroup->id)->toBe(2); + expect($tagGroup->label)->toBe('Region'); +}); + +it('can update a tag group', function () { + MockClient::global([ + UpdateTagGroupRequest::class => MockResponse::fixture('update-tag-group'), + ]); + + $tagGroup = $this->ohDear->updateTagGroup(1, [ + 'label' => 'Updated Environment', + ]); + + expect($tagGroup->id)->toBe(1); + expect($tagGroup->label)->toBe('Updated Environment'); +}); + +it('can delete a tag group', function () { + MockClient::global([ + DeleteTagGroupRequest::class => MockResponse::fixture('delete-tag-group'), + ]); + + $this->ohDear->deleteTagGroup(1); + + markTestComplete(); +}); diff --git a/tests/OhDearTests/TagsTest.php b/tests/OhDearTests/TagsTest.php new file mode 100644 index 0000000..d42e2ae --- /dev/null +++ b/tests/OhDearTests/TagsTest.php @@ -0,0 +1,38 @@ +ohDear = ohDearMock(); +}); + +it('can get tags', function () { + MockClient::global([ + GetTagsRequest::class => MockResponse::fixture('tags'), + ]); + + $tags = $this->ohDear->tags(); + + expect($tags)->toBeArray(); + foreach ($tags as $tag) { + expect($tag->id)->toBeInt(); + expect($tag->name)->toBeString(); + } +}); + +it('can create a tag', function () { + MockClient::global([ + CreateTagRequest::class => MockResponse::fixture('create-tag'), + ]); + + $tag = $this->ohDear->createTag([ + 'name' => 'staging', + 'team_id' => 19245, + ]); + + expect($tag->id)->toBe(2); + expect($tag->name)->toBe('staging'); +}); diff --git a/tests/Pest.php b/tests/Pest.php index 51acc4b..b768953 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,6 +1,5 @@ safeLoad(); - - $token = $_ENV['OH_DEAR_API_TOKEN'] ?? 'fake-token'; - $baseUrl = $_ENV['OH_DEAR_BASE_URL'] ?? 'https://ohdear.app/api/'; - - return new OhDear($token, $baseUrl); + return new OhDear('fake-token', 'https://ohdear.app/api/'); } function markTestComplete() diff --git a/tests/TestSupport/.env.example b/tests/TestSupport/.env.example deleted file mode 100644 index ba7e5fa..0000000 --- a/tests/TestSupport/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -OH_DEAR_API_TOKEN=your_api_token_here -OH_DEAR_BASE_URL=https://ohdear.app/api/ diff --git a/tests/TestSupport/scripts/real-test.php b/tests/TestSupport/scripts/real-test.php deleted file mode 100644 index 9a241cf..0000000 --- a/tests/TestSupport/scripts/real-test.php +++ /dev/null @@ -1,45 +0,0 @@ -safeLoad(); - -$token = $_ENV['OH_DEAR_API_TOKEN'] ?? null; -$baseUrl = $_ENV['OH_DEAR_BASE_URL'] ?? null; - -$ohDear = new OhDear($token, $baseUrl); - -/* -dump($ohDear->me()); - -$updated = $ohDear->updateMonitor(82063, [ - 'uptime_check_settings' => [ - 'look_for_string' => 'a string', - ], -]); - -dd($updated); - -$monitors = $ohDear->monitors(); - - -foreach ($monitors as $monitor) { - // dump($monitor->teamId); - // dump($monitor->id); -} - -// dump($ohDear->monitor(82062)); - -*/ - -$monitor = $ohDear->createMonitor([ - 'team_id' => 19245, - 'type' => 'http', - 'url' => 'https://laravel.com', -]); - -dump($monitor);