Skip to content

Commit 968ae59

Browse files
authored
fix: Add phpunit.xml.dist and fix Pest test configuration (#2) (#1)
- Add phpunit.xml.dist to provide proper PHPUnit/Pest configuration and avoid argument parsing issues with --cache-directory option - Fix ResponseRequest validation to use strict empty string check instead of empty() which incorrectly treats '0' as empty - Include tests and CI workflow from add-pest-tests-workflow branch
1 parent acf952e commit 968ae59

19 files changed

Lines changed: 1827 additions & 6 deletions

.github/workflows/tests.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
fail-fast: true
15+
matrix:
16+
php: [8.3]
17+
18+
name: PHP ${{ matrix.php }}
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Setup PHP
25+
uses: shivammathur/setup-php@v2
26+
with:
27+
php-version: ${{ matrix.php }}
28+
extensions: json, mbstring
29+
coverage: none
30+
31+
- name: Validate composer.json
32+
run: composer validate --strict
33+
34+
- name: Get Composer cache directory
35+
id: composer-cache
36+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
37+
38+
- name: Cache Composer dependencies
39+
uses: actions/cache@v4
40+
with:
41+
path: ${{ steps.composer-cache.outputs.dir }}
42+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
43+
restore-keys: ${{ runner.os }}-composer-
44+
45+
- name: Install dependencies
46+
run: composer install --prefer-dist --no-interaction --no-progress
47+
48+
- name: Run tests
49+
run: composer test

composer.json

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,36 @@
33
"description": "An unofficial PHP wrapper for the official Claim.MD API.",
44
"type": "library",
55
"license": "MIT",
6-
"version": "1.0.1",
76
"require": {
87
"php": ">=8.2",
98
"guzzlehttp/guzzle": "^7.9",
109
"ext-json": "*"
1110
},
11+
"require-dev": {
12+
"mockery/mockery": "^1.6",
13+
"pestphp/pest": "^3.0"
14+
},
1215
"autoload": {
1316
"psr-4": {
1417
"Nextvisit\\ClaimMDWrapper\\": "src/"
1518
}
1619
},
20+
"autoload-dev": {
21+
"psr-4": {
22+
"Nextvisit\\ClaimMDWrapper\\Tests\\": "tests/"
23+
}
24+
},
1725
"authors": [
1826
{
1927
"name": "Kyle Yannelli",
20-
"github": "kyleyannelli",
2128
"email": "kyleyannelli@gmail.com",
29+
"homepage": "https://github.com/kyleyannelli",
2230
"role": "Developer"
2331
},
2432
{
2533
"name": "Ryan Yannelli",
26-
"github": "yannelli",
2734
"email": "ryanyannelli@gmail.com",
35+
"homepage": "https://github.com/yannelli",
2836
"role": "Developer"
2937
}
3038
],
@@ -40,7 +48,14 @@
4048
"issues": "https://github.com/Nextvisit/claim-md-php/issues"
4149
},
4250
"config": {
43-
"sort-packages": true
51+
"sort-packages": true,
52+
"allow-plugins": {
53+
"pestphp/pest-plugin": true
54+
}
55+
},
56+
"scripts": {
57+
"test": "pest",
58+
"test:coverage": "pest --coverage"
4459
},
4560
"minimum-stability": "stable"
46-
}
61+
}

phpunit.xml.dist

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
cacheDirectory=".phpunit.cache"
7+
>
8+
<testsuites>
9+
<testsuite name="Unit">
10+
<directory>tests/Unit</directory>
11+
</testsuite>
12+
</testsuites>
13+
<source>
14+
<include>
15+
<directory>src</directory>
16+
</include>
17+
</source>
18+
</phpunit>

src/Requests/ResponseRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __construct(private readonly Client $client) {}
4242
*/
4343
public function fetchResponses(string $responseId, ?string $claimId = null): array
4444
{
45-
if (empty($responseId)) {
45+
if ($responseId === '') {
4646
throw new InvalidArgumentException('ResponseID cannot be empty');
4747
}
4848

tests/Pest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
|--------------------------------------------------------------------------
5+
| Test Case
6+
|--------------------------------------------------------------------------
7+
|
8+
| The closure you provide to your test functions is always bound to a specific PHPUnit test
9+
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
10+
| need to change it using the "pest()" function to bind a different classes or traits.
11+
|
12+
*/
13+
14+
pest()->extend(Nextvisit\ClaimMDWrapper\Tests\TestCase::class)->in('Unit');
15+
16+
/*
17+
|--------------------------------------------------------------------------
18+
| Expectations
19+
|--------------------------------------------------------------------------
20+
|
21+
| When you're writing tests, you often need to check that values meet certain conditions. The
22+
| "expect()" function gives you access to a set of "expectations" methods that you can use
23+
| to assert different things. Of course, you may extend the Expectation API at any time.
24+
|
25+
*/
26+
27+
/*
28+
|--------------------------------------------------------------------------
29+
| Functions
30+
|--------------------------------------------------------------------------
31+
|
32+
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
33+
| project that you don't want to repeat in every file. Here you can also expose helpers as
34+
| global functions to help you to reduce the number of lines of code in your test files.
35+
|
36+
*/

tests/TestCase.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Nextvisit\ClaimMDWrapper\Tests;
4+
5+
use PHPUnit\Framework\TestCase as BaseTestCase;
6+
7+
abstract class TestCase extends BaseTestCase
8+
{
9+
//
10+
}

tests/Unit/ClientTest.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
use GuzzleHttp\Client as GuzzleClient;
4+
use GuzzleHttp\Handler\MockHandler;
5+
use GuzzleHttp\HandlerStack;
6+
use GuzzleHttp\Psr7\Response;
7+
use GuzzleHttp\Middleware;
8+
use Nextvisit\ClaimMDWrapper\Client;
9+
use Nextvisit\ClaimMDWrapper\Config;
10+
11+
describe('Client', function () {
12+
it('creates a client with account key and config', function () {
13+
$client = new Client('test-account-key');
14+
15+
expect($client)->toBeInstanceOf(Client::class);
16+
});
17+
18+
it('creates a client with custom config', function () {
19+
$config = new Config();
20+
$client = new Client('test-account-key', $config);
21+
22+
expect($client)->toBeInstanceOf(Client::class);
23+
});
24+
25+
it('sends a POST request with account key in form data', function () {
26+
$container = [];
27+
$history = Middleware::history($container);
28+
29+
$mock = new MockHandler([
30+
new Response(200, [], json_encode(['status' => 'success'])),
31+
]);
32+
33+
$handlerStack = HandlerStack::create($mock);
34+
$handlerStack->push($history);
35+
36+
$guzzleClient = new GuzzleClient(['handler' => $handlerStack]);
37+
$client = new Client('test-account-key', new Config(), $guzzleClient);
38+
39+
$result = $client->sendRequest('POST', '/test-endpoint', ['data' => 'value']);
40+
41+
expect($result)->toBe(['status' => 'success']);
42+
expect($container)->toHaveCount(1);
43+
44+
$request = $container[0]['request'];
45+
expect($request->getMethod())->toBe('POST');
46+
expect((string) $request->getUri())->toBe('/test-endpoint');
47+
48+
$body = (string) $request->getBody();
49+
expect($body)->toContain('AccountKey=test-account-key');
50+
expect($body)->toContain('data=value');
51+
});
52+
53+
it('sends a multipart request when isMultipart is true', function () {
54+
$container = [];
55+
$history = Middleware::history($container);
56+
57+
$mock = new MockHandler([
58+
new Response(200, [], json_encode(['uploaded' => true])),
59+
]);
60+
61+
$handlerStack = HandlerStack::create($mock);
62+
$handlerStack->push($history);
63+
64+
$guzzleClient = new GuzzleClient(['handler' => $handlerStack]);
65+
$client = new Client('test-account-key', new Config(), $guzzleClient);
66+
67+
$result = $client->sendRequest('POST', '/upload', ['file' => 'content'], true);
68+
69+
expect($result)->toBe(['uploaded' => true]);
70+
71+
$request = $container[0]['request'];
72+
$contentType = $request->getHeaderLine('Content-Type');
73+
expect($contentType)->toContain('multipart/form-data');
74+
});
75+
76+
it('includes additional headers when provided', function () {
77+
$container = [];
78+
$history = Middleware::history($container);
79+
80+
$mock = new MockHandler([
81+
new Response(200, [], json_encode(['data' => 'test'])),
82+
]);
83+
84+
$handlerStack = HandlerStack::create($mock);
85+
$handlerStack->push($history);
86+
87+
$guzzleClient = new GuzzleClient(['handler' => $handlerStack]);
88+
$client = new Client('test-account-key', new Config(), $guzzleClient);
89+
90+
$result = $client->sendRequest('POST', '/test', [], false, ['X-Custom-Header' => 'custom-value']);
91+
92+
$request = $container[0]['request'];
93+
expect($request->getHeaderLine('X-Custom-Header'))->toBe('custom-value');
94+
});
95+
96+
it('sends request without extra data', function () {
97+
$container = [];
98+
$history = Middleware::history($container);
99+
100+
$mock = new MockHandler([
101+
new Response(200, [], json_encode(['status' => 'ok'])),
102+
]);
103+
104+
$handlerStack = HandlerStack::create($mock);
105+
$handlerStack->push($history);
106+
107+
$guzzleClient = new GuzzleClient(['handler' => $handlerStack]);
108+
$client = new Client('test-account-key', new Config(), $guzzleClient);
109+
110+
$result = $client->sendRequest('POST', '/simple');
111+
112+
expect($result)->toBe(['status' => 'ok']);
113+
114+
$body = (string) $container[0]['request']->getBody();
115+
expect($body)->toContain('AccountKey=test-account-key');
116+
});
117+
});

tests/Unit/ConfigTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
use Nextvisit\ClaimMDWrapper\Config;
4+
5+
describe('Config', function () {
6+
it('returns the correct base URI', function () {
7+
$config = new Config();
8+
9+
expect($config->getBaseUri())->toBe('https://svc.claim.md/');
10+
});
11+
12+
it('returns a string for base URI', function () {
13+
$config = new Config();
14+
15+
expect($config->getBaseUri())->toBeString();
16+
});
17+
});

0 commit comments

Comments
 (0)