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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
max-parallel: 10
matrix:
php: [ '8.0', '8.1', '8.2', '8.3' ]
php: [ '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]

steps:
- name: Set up PHP
Expand All @@ -20,7 +20,7 @@ jobs:
tools: composer:v2

- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Download dependencies
run: composer update --no-interaction --prefer-dist
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.5'
coverage: none

- name: Download dependencies
Expand All @@ -32,12 +32,12 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.5'
coverage: none

- name: Download dependencies
Expand All @@ -55,12 +55,12 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
php-version: '8.5'
coverage: none

- name: Download dependencies
Expand Down
4 changes: 3 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
],
'phpdoc_separation' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_to_comment' => true,
'phpdoc_to_comment' => [
'ignored_tags' => ['var'],
],
'phpdoc_trim' => true,
'phpdoc_var_without_name' => true,
'return_type_declaration' => [
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG-4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [4.3.0] - 2026-03-20
### Added
- PHP 8.4 support
- PHP 8.5 support
- Configurable default headers support via `headers` module configuration
- Improved test coverage with unit and functional tests

### Changed
- Upgraded PHPStan to v2
- Upgraded Psalm to v6
- Updated static analysis workflow to use PHP 8.5

## [4.2.0] - 2024-03-15
### Added
- PHP 8.3 support
Expand Down
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,23 @@ modules:
```

The `application` property is a relative path to file which returns your `Slim\App` instance.

You can also configure default headers that will be sent with every request using the `headers` option:

```yaml
modules:
enabled:
- REST:
depends: DoclerLabs\CodeceptionSlimModule\Module\Slim

config:
DoclerLabs\CodeceptionSlimModule\Module\Slim:
application: path/to/application.php
headers:
Content-Type: application/json
Accept: application/json
```

Here is the minimum `application.php` content:

```php
Expand All @@ -68,7 +85,6 @@ return $app;
## Testing your API endpoints

```php

class UserCest
{
public function getUserReturnsWithEmail(FunctionalTester $I): void
Expand All @@ -86,3 +102,32 @@ class UserCest
}
}
```

### With default headers

When you configure default `headers` in your suite configuration, you no longer need to set them manually in each test:

```php
class UserCest
{
// Content-Type and Accept headers are already set via module config
public function getUserReturnsWithEmail(FunctionalTester $I): void
{
$I->sendGET('/users/John');

$I->seeResponseCodeIs(200);
$I->seeResponseContainsJson(
[
'email' => 'john.doe@example.com',
]
);
}

public function createUserReturnsCreated(FunctionalTester $I): void
{
$I->sendPOST('/users', ['name' => 'Jane', 'email' => 'jane.doe@example.com']);

$I->seeResponseCodeIs(201);
}
}
```
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"autoload-dev": {
"psr-4": {
"DoclerLabs\\CodeceptionSlimModule\\Test\\": "test/support",
"DoclerLabs\\CodeceptionSlimModule\\Test\\Functional\\": "test/suite/functional"
"DoclerLabs\\CodeceptionSlimModule\\Test\\Functional\\": "test/suite/functional",
"DoclerLabs\\CodeceptionSlimModule\\Test\\Unit\\": "test/suite/unit"
}
},
"config": {
Expand Down
6 changes: 5 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ includes:

parameters:
level: max
checkMissingIterableValueType: false
ignoreErrors:
-
identifier: missingType.iterableValue
paths:
- src
fileExtensions:
- php
bootstrapFiles:
- vendor/autoload.php
5 changes: 5 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@
<directory name="vendor" />
</ignoreFiles>
</projectFiles>

<issueHandlers>
<MissingOverrideAttribute errorLevel="suppress" />
<UnusedClass errorLevel="suppress" />
</issueHandlers>
</psalm>
39 changes: 20 additions & 19 deletions src/Lib/Connector/SlimPsr7.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace DoclerLabs\CodeceptionSlimModule\Lib\Connector;

use Psr\Container\ContainerInterface;
use Psr\Http\Message\UploadedFileInterface;
use Slim\App;
use Slim\Psr7\Cookies;
Expand All @@ -16,11 +17,15 @@
use Symfony\Component\BrowserKit\Request as BrowserKitRequest;
use Symfony\Component\BrowserKit\Response as BrowserKitResponse;

/**
* @extends AbstractBrowser<BrowserKitRequest, BrowserKitResponse>
*/
class SlimPsr7 extends AbstractBrowser
{
/** @var App */
private $app;
/** @var App<ContainerInterface|null> */
private App $app;

/** @param App<ContainerInterface|null> $app */
public function setApp(App $app): void
{
$this->app = $app;
Expand Down Expand Up @@ -104,33 +109,29 @@ private function convertToHeaders(array $serverVariables): Headers
/**
* Convert uploaded file list to UploadedFile instances.
*
* @param array $files List of uploaded file instances, that implements `Psr\Http\Message\UploadedFileInterface`,
* or meta data about uploaded file items from $_FILES, indexed with field name.
*
* @return array<string, UploadedFileInterface>
*/
private function convertFiles(array $files): array
{
$uploadedFiles = [];
foreach ($files as $fieldName => $file) {
if ($file instanceof UploadedFileInterface) {
$uploadedFiles[$fieldName] = $file;
} elseif (!isset($file['tmp_name']) && !isset($file['name'])) {
$uploadedFiles[$fieldName] = $this->createUploadedFile($file);
$uploadedFiles[(string)$fieldName] = $file;
} elseif (
is_array($file)
&& isset($file['tmp_name'], $file['name'])
) {
/** @var array{tmp_name: string, name: string, type?: string|null, size?: int|null, error?: int} $file */
$uploadedFiles[(string)$fieldName] = new UploadedFile(
$file['tmp_name'],
$file['name'],
$file['type'] ?? null,
$file['size'] ?? null,
$file['error'] ?? UPLOAD_ERR_OK
);
}
}

return $uploadedFiles;
}

private function createUploadedFile(array $file): UploadedFile
{
return new UploadedFile(
$file['tmp_name'],
$file['name'],
$file['type'],
$file['size'],
$file['error']
);
}
}
31 changes: 22 additions & 9 deletions src/Module/Slim.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Codeception\Lib\Framework;
use Codeception\TestInterface;
use DoclerLabs\CodeceptionSlimModule\Lib\Connector\SlimPsr7;
use Psr\Container\ContainerInterface;
use Slim\App;

/**
Expand All @@ -20,13 +21,16 @@
* ### Slim 4.x
*
* * application - Relative path to file which bootstrap and returns your `Slim\App` instance.
* * headers - Default headers to be sent with every request (optional).
*
* #### Example (`test/suite/functional.suite.yml`)
* ```yaml
* modules:
* config:
* DoclerLabs\CodeceptionSlimModule\Module\Slim:
* application: 'app/bootstrap.php'
* headers:
* Content-Type: application/json
* ```
*
* ## Public Properties
Expand All @@ -45,22 +49,26 @@
* config:
* DoclerLabs\CodeceptionSlimModule\Module\Slim:
* application: 'app/bootstrap.php'
* headers:
* Content-Type: application/json
* ```
*/
class Slim extends Framework
{
/** @var App */
public $app;
/** @var App<ContainerInterface|null> */
public App $app;

/** @var array */
protected array $requiredFields = ['application'];

/** @var string */
private $applicationPath;
protected array $config = ['headers' => []];

private string $applicationPath;

public function _initialize(): void
{
$applicationPath = Configuration::projectDir() . $this->config['application'];
/** @var string $configApplication */
$configApplication = $this->config['application'];
$applicationPath = Configuration::projectDir() . $configApplication;
if (!is_readable($applicationPath)) {
throw new ModuleConfigException(
static::class,
Expand All @@ -75,11 +83,10 @@ public function _initialize(): void

public function _before(TestInterface $test): void
{
/* @noinspection PhpIncludeInspection */
$this->app = require $this->applicationPath;
$app = require $this->applicationPath;

// Check if app instance is ready.
if (!$this->app instanceof App) {
if (!$app instanceof App) {
throw new ConfigurationException(
sprintf(
"Unable to bootstrap slim application.\n Application file must return with `%s` instance.",
Expand All @@ -88,11 +95,17 @@ public function _before(TestInterface $test): void
);
}

$this->app = $app;

$connector = new SlimPsr7();
$connector->setApp($this->app);

$this->client = $connector;

/** @var array<string, string> $headers */
$headers = $this->config['headers'];
$this->headers = $headers;

parent::_before($test);
}
}
2 changes: 2 additions & 0 deletions test/suite/functional.suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ modules:
config:
DoclerLabs\CodeceptionSlimModule\Module\Slim:
application: test/support/Fake/application.php
headers:
X-Default-Header: default-value
Loading