Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC
name: Tests

on:
push:
branches: [main, master, "feature/**"]
pull_request:

jobs:
phpunit:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ["8.4"]
name: PHPUnit (PHP ${{ matrix.php }})
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- run: composer install --no-interaction --no-progress
- run: vendor/bin/phpunit
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC
# CLI-only test runner for this library — no MySQL/FPM required.
# Usage (on host):
# docker compose run --rm php
# Runs `composer install` then PHPUnit against tests/.
services:
php:
build:
dockerfile_inline: |
FROM php:8.4-cli-alpine
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
working_dir: /repo
volumes:
- .:/repo
command: sh -c "composer install --no-interaction --no-progress && vendor/bin/phpunit"
57 changes: 57 additions & 0 deletions tests/Exception/ExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
// file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC

declare(strict_types=1);

namespace Dmstr\Bc4Client\Tests\Exception;

use Dmstr\Bc4Client\Exception\Bc4ApiException;
use Dmstr\Bc4Client\Exception\InvalidGrantException;
use Dmstr\Bc4Client\Exception\RequestException;
use PHPUnit\Framework\TestCase;

/**
* Unit tests for the BC4 client exception hierarchy — verifies the type
* relationships callers rely on for catch-block dispatch, plus the
* RequestException payload accessors.
*/
final class ExceptionTest extends TestCase
{
public function testBc4ApiExceptionIsRuntimeException(): void
{
self::assertInstanceOf(\RuntimeException::class, new Bc4ApiException('boom'));
}

public function testInvalidGrantExceptionExtendsBc4ApiException(): void
{
$exception = new InvalidGrantException('refresh token rejected');

self::assertInstanceOf(Bc4ApiException::class, $exception);
self::assertInstanceOf(\RuntimeException::class, $exception);
self::assertSame('refresh token rejected', $exception->getMessage());
}

public function testRequestExceptionExposesStatusAndBody(): void
{
$exception = new RequestException('Not Found', 404, '{"error":"missing"}');

self::assertInstanceOf(Bc4ApiException::class, $exception);
self::assertSame('Not Found', $exception->getMessage());
self::assertSame(404, $exception->getStatusCode());
self::assertSame('{"error":"missing"}', $exception->getResponseBody());
self::assertSame(0, $exception->getCode());
}

public function testRequestExceptionResponseBodyDefaultsToEmpty(): void
{
self::assertSame('', (new RequestException('Server Error', 500))->getResponseBody());
}

public function testRequestExceptionPreservesPreviousThrowable(): void
{
$previous = new \LogicException('root cause');
$exception = new RequestException('Bad Gateway', 502, '', $previous);

self::assertSame($previous, $exception->getPrevious());
}
}
Loading