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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ jobs:
phpunit-dev:
uses: php-forge/actions/.github/workflows/phpunit.yml@v2
with:
composer-command: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ignore-platform-reqs --ansi
concurrency-group: phpunit-${{ github.workflow }}-${{ github.ref }}-dev
extensions: mbstring, gd
ignore-platform-reqs: true
os: '["ubuntu-latest"]'
php-version: '["8.5","8.6"]'
secrets:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Bug #181: Add permissions to workflow files for enhanced access control (@terabytesoftw)
- Bug #182: Remove redundant cookie collection tests in `CookiesPsr7Test` for clarity (@terabytesoftw)
- Bug #183: Remove redundant cookie tests from `ResponseAdapterTest` for clarity (@terabytesoftw)
- Bug #184: Remove redundant remote IP and server port from `ServerParamsPsr7Test` for clarity (@terabytesoftw)

## 0.1.0 September 26, 2025

Expand Down
68 changes: 17 additions & 51 deletions tests/adapter/ServerParamsPsr7Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@
use function sprintf;
use function var_export;

/**
* Test suite for PSR-7 server parameters adapter in the Yii2 bridge layer.
*
* Verifies correct behavior of the Request server parameter handling when using PSR-7 requests, including remote host,
* remote IP, script name, server name, server port, and server params precedence and reset logic.
*
* Test coverage.
* - Checks correct extraction of server parameters from PSR-7 requests and fallback to global server values.
* - Confirms empty values and default handling for script URL and server params in various modes.
* - Ensures independent requests maintain separate server parameter states.
* - Uses data providers where applicable (remote host, server name, server params); remote IP and server port are
* covered via targeted tests.
* - Validates reset and override behavior for remote host, server name, and server port.
*
* @copyright Copyright (C) 2025 Terabytesoftw.
* @license https://opensource.org/license/bsd-3-clause BSD 3-Clause License.
*/
#[Group('adapter')]
final class ServerParamsPsr7Test extends TestCase
{
Expand Down Expand Up @@ -192,30 +209,6 @@ public function testReturnRemoteIPFromPsr7ServerParamsOverridesGlobalServer(): v
);
}

#[DataProviderExternal(ServerParamsPsr7Provider::class, 'remoteIPCases')]
#[Group('remote-ip')]
public function testReturnRemoteIPFromServerParamsCases(mixed $serverValue, string|null $expected): void
{
$request = new Request();

$request->setPsr7Request(
FactoryHelper::createRequest('GET', '/test', serverParams: ['REMOTE_ADDR' => $serverValue]),
);

$actual = $request->getRemoteIP();

self::assertSame(
$expected,
$actual,
sprintf(
"'getRemoteIP()' should return '%s' when 'REMOTE_ADDR' is '%s' in PSR-7 'serverParams'. Got: '%s'",
var_export($expected, true),
var_export($serverValue, true),
var_export($actual, true),
),
);
}

/**
* @throws InvalidConfigException if the configuration is invalid or incomplete.
*/
Expand Down Expand Up @@ -530,33 +523,6 @@ public function testServerPortAfterRequestReset(): void
);
}

/**
* @phpstan-param array<string, mixed> $requestConfig
* @phpstan-param array<string, mixed> $serverGlobal
* @phpstan-param array<string, array<int, string>|int|string> $headers
* @phpstan-param array<string, mixed> $serverParams
*/
#[DataProviderExternal(ServerParamsPsr7Provider::class, 'serverPortCases')]
#[Group('server-port')]
public function testServerPortCases(
array $requestConfig,
array $serverGlobal,
array $headers,
array $serverParams,
int|null $expected,
string $message,
): void {
$_SERVER = $serverGlobal;

$request = new Request($requestConfig);

$request->setPsr7Request(
FactoryHelper::createRequest('GET', '/test', $headers, serverParams: $serverParams),
);

self::assertSame($expected, $request->getServerPort(), $message);
}

#[Group('server-port')]
public function testServerPortIndependentRequestsWithDifferentPorts(): void
{
Expand Down
271 changes: 0 additions & 271 deletions tests/provider/ServerParamsPsr7Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,103 +75,6 @@ public static function remoteHostCases(): array
];
}

/**
* @phpstan-return array<array-key, array{mixed, string|null}>
*/
public static function remoteIPCases(): array
{
return [
'boolean-false' => [
false,
null,
],
'boolean-true' => [
true,
null,
],
'empty-array' => [
[],
null,
],
'empty-string' => [
'',
null,
],
'float' => [
123.45,
null,
],
'integer' => [
12345,
null,
],
'integer-zero' => [
0,
null,
],
'invalid-ip' => [
'999.999.999.999',
null,
],
'IPv4' => [
'192.168.1.100',
'192.168.1.100',
],
'ipv4-with-port' => [
'10.0.0.1:8080',
null,
],
'IPv4-local' => [
'127.0.0.1',
'127.0.0.1',
],
'IPv6' => [
'2001:0db8:85a3:0000:0000:8a2e:0370:7334',
'2001:0db8:85a3:0000:0000:8a2e:0370:7334',
],
'ipv6-bracketed' => [
'[::1]',
null,
],
'IPv6-compressed' => [
'::1',
'::1',
],
'ipv6-with-port' => [
'[::1]:443',
null,
],
'localhost' => [
'localhost',
null,
],
'null' => [
null,
null,
],
'numeric string' => [
'123',
null,
],
'object' => [
(object) ['foo' => 'bar'],
null,
],
'spaces-around' => [
' 127.0.0.1 ',
null,
],
'string-zero' => [
'0',
null,
],
'zero-address' => [
'0.0.0.0',
'0.0.0.0',
],
];
}

/**
* @phpstan-return array<array-key, array{mixed, string|null}>
*/
Expand Down Expand Up @@ -379,178 +282,4 @@ public static function serverParamDefaultValueCases(): array
],
];
}

/**
* @phpstan-return array<
* string,
* array{
* array<string, mixed>,
* array<string, mixed>,
* array<string, array<int, string>|int|string>,
* array<string, mixed>,
* int|null,
* string,
* }
* >
*/
public static function serverPortCases(): array
{
return [
'Forwarded port when request from trusted proxy' => [
[
'portHeaders' => ['X-Forwarded-Port'],
'trustedHosts' => ['10.0.0.0/24'], // trust this subnet
],
['REMOTE_ADDR' => '10.0.0.1'],
['X-Forwarded-Port' => '443'],
[
'SERVER_PORT' => '8080',
'REMOTE_ADDR' => '10.0.0.1',
],
443,
"'getServerPort()' should return forwarded port when request comes from trusted proxy.",
],
'Ignore forwarded port when request from untrusted host' => [
[
'portHeaders' => ['X-Forwarded-Port'],
'secureHeaders' => ['X-Forwarded-Port'],
'trustedHosts' => ['10.0.0.0/24'], // only trust this subnet
],
['REMOTE_ADDR' => '192.168.1.100'],
['X-Forwarded-Port' => '443'],
[
'REMOTE_ADDR' => '192.168.1.100',
'SERVER_PORT' => '8080',
],
8080,
"'getServerPort()' should ignore forwarded port header from untrusted hosts and use 'SERVER_PORT'.",
],
'Null when PSR-7 request server port is empty array' => [
[],
[],
[],
['SERVER_PORT' => []],
null,
"'SERVER_PORT' should return 'null' from PSR-7 'serverParams' when adapter is set but 'SERVER_PORT' " .
'is an empty array.',
],
'Null when PSR-7 request server port is null' => [
[],
[],
[],
['SERVER_PORT' => null],
null,
"'SERVER_PORT' should return 'null' from PSR-7 'serverParams' when adapter is set but 'SERVER_PORT' " .
"is 'null'.",
],
'Null when PSR-7 request server port is not present' => [
[],
[],
[],
['HTTP_HOST' => 'example.com'],
null,
"'SERVER_PORT' should return 'null' from PSR-7 'serverParams' when adapter is set but 'SERVER_PORT' " .
'is not present.',
],
'Null when PSR-7 request server port is not string' => [
[],
[],
[],
['SERVER_PORT' => ['invalid' => 'array']],
null,
"'SERVER_PORT' should return 'null' from PSR-7 'serverParams' when adapter is set but 'SERVER_PORT' " .
'is not a string.',
],
'Server port as integer when PSR-7 server port.' => [
[],
[],
[],
['SERVER_PORT' => '443'],
443,
"'getServerPort()' should return integer value when 'SERVER_PORT' is a numeric string.",
],
'Server port as integer when PSR-7 server port is numeric string' => [
[],
[],
[],
['SERVER_PORT' => '443'],
443,
"'getServerPort()' should return integer value when 'SERVER_PORT' is a numeric string.",
],
'Server port from comma separated forwarded header' => [
[
'portHeaders' => ['X-Forwarded-Port'],
'secureHeaders' => ['X-Forwarded-Port'],
'trustedHosts' => ['127.0.0.1'],
],
['REMOTE_ADDR' => '127.0.0.1'],
['X-Forwarded-Port' => '9443, 7443'],
[
'REMOTE_ADDR' => '127.0.0.1',
'SERVER_PORT' => '80',
],
9443,
"'getServerPort()' should return the first port from a comma-separated 'X-Forwarded-Port' header.",
],
'Server port from first valid forwarded header when multiple configured' => [
[
'portHeaders' => [
'X-Custom-Port',
'X-Forwarded-Port',
'X-Real-Port',
],
'secureHeaders' => [
'X-Custom-Port',
'X-Forwarded-For',
'X-Forwarded-Host',
'X-Forwarded-Port',
'X-Forwarded-Proto',
'X-Real-Port',
],
'trustedHosts' => ['127.0.0.1'],
],
['REMOTE_ADDR' => '127.0.0.1'],
[
'X-Custom-Port' => '',
'X-Forwarded-Port' => '9443',
'X-Real-Port' => '7443',
],
[
'REMOTE_ADDR' => '127.0.0.1',
'SERVER_PORT' => '80',
],
9443,
"'getServerPort()' should return the port from the first valid forwarded header in the configured " .
'list.',
],
'Server port from forwarded header when adapter is set' => [
[
'portHeaders' => ['X-Forwarded-Port'],
'trustedHosts' => ['127.0.0.1'],
],
['REMOTE_ADDR' => '127.0.0.1'],
['X-Forwarded-Port' => '443'],
[
'REMOTE_ADDR' => '127.0.0.1',
'SERVER_PORT' => '8080',
],
443,
"'getServerPort()' should return the port from 'X-Forwarded-Port' header when present, ignoring " .
"'SERVER_PORT' from PSR-7 'serverParams'.",
],
'Server port from PSR-7 request when adapter is set and server port present' => [
[
'portHeaders' => [
'X-Custom-Port',
'X-Forwarded-Port',
],
],
[],
['X-Custom-Port' => ''],
['SERVER_PORT' => '3000'],
3000,
"'getServerPort()' should fallback to 'SERVER_PORT' when all forwarded headers are 'null' or missing.",
],
];
}
}
Loading