Skip to content

Modernize codebase and add more code quality tools #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 28, 2024
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
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
-
package-ecosystem: composer
directory: "/"
schedule:
interval: monthly
versioning-strategy: auto
groups:
dev-dependencies:
dependency-type: "development"
10 changes: 8 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ jobs:

strategy:
matrix:
php: [8.0, 8.1]
php: [8.1, 8.2, 8.3]

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

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand All @@ -26,6 +26,12 @@ jobs:
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-interaction --no-suggest

- name: Execute Code Sniffer
run: vendor/bin/phpcs

- name: Execute PHP Stan
run: vendor/bin/phpstan

- name: Run test suite
run: |
php -S 127.0.0.1:8000 -t tests/data/app >/dev/null 2>&1 &
Expand Down
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
],
"homepage": "https://codeception.com/",
"require": {
"php": "^8.0",
"php": "^8.1",
"ext-json": "*",
"codeception/codeception": "*@dev",
"codeception/lib-innerbrowser": "*@dev",
"guzzlehttp/guzzle": "^7.4",
"symfony/browser-kit": "^5.4 || ^6.0 || ^7.0"
"symfony/browser-kit": "^5.4 | ^6.0 | ^7.0"
},
"require-dev": {
"ext-curl": "*",
"squizlabs/php_codesniffer": "^3.10",
"phpstan/phpstan": "^1.10",
"aws/aws-sdk-php": "^3.199",
"codeception/module-rest": "^2.0 || *@dev"
"codeception/module-rest": "^2.0 | *@dev"
},
"conflict": {
"codeception/codeception": "<5.0",
Expand All @@ -37,7 +39,6 @@
"suggest": {
"codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests"
},
"minimum-stability": "dev",
"autoload": {
"classmap": [
"src/"
Expand Down
23 changes: 23 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer" xsi:noNamespaceSchemaLocation="phpcs.xsd">
<description>The coding standard.</description>

<config name="testVersion" value="8.1-"/>

<file>src</file>

<arg name="basepath" value="./"/>
<arg name="colors"/>
<arg name="parallel" value="5"/>
<arg value="np"/>

<rule ref="Internal.Tokenizer.Exception">
<type>error</type>
</rule>

<rule ref="PSR12"/>

<rule ref="PSR2.Methods.MethodDeclaration.Underscore">
<type>warning</type>
</rule>
</ruleset>
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
parameters:
paths:
- ./src
level: 5
58 changes: 39 additions & 19 deletions src/Codeception/Lib/Connector/Guzzle.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

class Guzzle extends AbstractBrowser
{
/**
* @var array<string, mixed>
*/
protected array $requestOptions = [
'allow_redirects' => false,
'headers' => [],
Expand Down Expand Up @@ -115,7 +118,7 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons
$contentType = 'text/html';
}

if (strpos($contentType, 'charset=') === false) {
if (str_contains($contentType, 'charset=') === false) {
if (preg_match('#<meta[^>]+charset *= *["\']?([a-zA-Z\-0-9]+)#i', $body, $matches)) {
$contentType .= ';charset=' . $matches[1];
}
Expand Down Expand Up @@ -159,10 +162,10 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons
protected function getAbsoluteUri(string $uri): string
{
$baseUri = $this->client->getConfig('base_uri');
if (strpos($uri, '://') === false && strpos($uri, '//') !== 0) {
if (strpos($uri, '/') === 0) {
if (str_contains($uri, '://') === false && !str_starts_with($uri, '//')) {
if (str_starts_with($uri, '/')) {
$baseUriPath = $baseUri->getPath();
if (!empty($baseUriPath) && strpos($uri, (string) $baseUriPath) === 0) {
if (!empty($baseUriPath) && str_starts_with($uri, (string) $baseUriPath)) {
$uri = substr($uri, strlen($baseUriPath));
}

Expand All @@ -178,9 +181,9 @@ protected function getAbsoluteUri(string $uri): string
return Uri::mergeUrls((string)$baseUri, $uri);
}

protected function doRequest($request)
protected function doRequest(object $request)
{
/** @var $request BrowserKitRequest **/
/** @var BrowserKitRequest $request **/
$guzzleRequest = new Psr7Request(
$request->getMethod(),
$request->getUri(),
Expand All @@ -190,17 +193,17 @@ protected function doRequest($request)
$options = $this->requestOptions;
$options['cookies'] = $this->extractCookies($guzzleRequest->getUri()->getHost());
$multipartData = $this->extractMultipartFormData($request);
if (!empty($multipartData)) {
if ($multipartData !== []) {
$options['multipart'] = $multipartData;
}

$formData = $this->extractFormData($request);
if (empty($multipartData) && $formData) {
if ($multipartData === [] && $formData) {
$options['form_params'] = $formData;
}

try {
if (null !== $this->awsCredentials) {
if ($this->awsCredentials instanceof AwsCredentials) {
$response = $this->client->send($this->awsSignature->signRequest($guzzleRequest, $this->awsCredentials), $options);
} else {
$response = $this->client->send($guzzleRequest, $options);
Expand All @@ -213,6 +216,7 @@ protected function doRequest($request)
$response = $exception->getResponse();
}

// @phpstan-ignore-next-line
return $this->createResponse($response);
}

Expand All @@ -227,7 +231,7 @@ protected function extractHeaders(BrowserKitRequest $request): array
$contentHeaders = ['Content-Length' => true, 'Content-Md5' => true, 'Content-Type' => true];
foreach ($server as $header => $val) {
$header = html_entity_decode(implode('-', array_map('ucfirst', explode('-', strtolower(str_replace('_', '-', $header))))), ENT_NOQUOTES);
if (strpos($header, 'Http-') === 0) {
if (str_starts_with($header, 'Http-')) {
$headers[substr($header, 5)] = $val;
} elseif (isset($contentHeaders[$header])) {
$headers[$header] = $val;
Expand All @@ -237,6 +241,9 @@ protected function extractHeaders(BrowserKitRequest $request): array
return $headers;
}

/**
* @return array<int, mixed>|null
*/
protected function extractFormData(BrowserKitRequest $browserKitRequest): ?array
{
if (!in_array(strtoupper($browserKitRequest->getMethod()), ['POST', 'PUT', 'PATCH', 'DELETE'])) {
Expand All @@ -257,14 +264,17 @@ protected function extractFormData(BrowserKitRequest $browserKitRequest): ?array
return $browserKitRequest->getParameters();
}

protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest)
/**
* @return array<string, mixed>
*/
protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest): array
{
if (!in_array(strtoupper($browserKitRequest->getMethod()), ['POST', 'PUT', 'PATCH'])) {
return [];
}

$parts = $this->mapFiles($browserKitRequest->getFiles());
if (empty($parts)) {
if ($parts === []) {
return [];
}

Expand All @@ -275,11 +285,14 @@ protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest
return $parts;
}

protected function formatMultipart($parts, $key, $value)
/**
* @return array<string, mixed>
*/
protected function formatMultipart(mixed $parts, string $key, mixed $value): array
{
if (is_array($value)) {
foreach ($value as $subKey => $subValue) {
$parts = array_merge($this->formatMultipart([], $key.sprintf('[%s]', $subKey), $subValue), $parts);
$parts = array_merge($this->formatMultipart([], $key . sprintf('[%s]', $subKey), $subValue), $parts);
}

return $parts;
Expand All @@ -289,7 +302,11 @@ protected function formatMultipart($parts, $key, $value)
return $parts;
}

protected function mapFiles($requestFiles, $arrayName = ''): array
/**
* @param array<int, mixed> $requestFiles
* @return array<int, mixed>
*/
protected function mapFiles(array $requestFiles, ?string $arrayName = ''): array
{
$files = [];
foreach ($requestFiles as $name => $info) {
Expand Down Expand Up @@ -329,7 +346,7 @@ protected function mapFiles($requestFiles, $arrayName = ''): array
return $files;
}

protected function extractCookies($host): GuzzleCookieJar
protected function extractCookies(string $host): GuzzleCookieJar
{
$jar = [];
$cookies = $this->getCookieJar()->all();
Expand All @@ -345,7 +362,7 @@ protected function extractCookies($host): GuzzleCookieJar
return new GuzzleCookieJar(false, $jar);
}

public static function createHandler($handler): GuzzleHandlerStack
public static function createHandler(mixed $handler): GuzzleHandlerStack
{
if ($handler instanceof GuzzleHandlerStack) {
return $handler;
Expand All @@ -360,7 +377,7 @@ public static function createHandler($handler): GuzzleHandlerStack
}

if (is_string($handler) && class_exists($handler)) {
return GuzzleHandlerStack::create(new $handler);
return GuzzleHandlerStack::create(new $handler());
}

if (is_callable($handler)) {
Expand All @@ -370,7 +387,10 @@ public static function createHandler($handler): GuzzleHandlerStack
return GuzzleHandlerStack::create();
}

public function setAwsAuth($config): void
/**
* @param array<string, mixed> $config
*/
public function setAwsAuth(array $config): void
{
$this->awsCredentials = new AwsCredentials($config['key'], $config['secret']);
$this->awsSignature = new AwsSignatureV4($config['service'], $config['region']);
Expand Down
40 changes: 23 additions & 17 deletions src/Codeception/Module/PhpBrowser.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public function _initialize()

public function _before(TestInterface $test)
{
if (!$this->client) {
if (!$this->client instanceof AbstractBrowser) {
$this->client = new Guzzle();
}

Expand All @@ -155,12 +155,14 @@ public function setHeader(string $name, string $value): void
$this->haveHttpHeader($name, $value);
}

public function amHttpAuthenticated($username, $password): void
public function amHttpAuthenticated(string $username, string $password): void
{
$this->client->setAuth($username, $password);
if ($this->client instanceof Guzzle) {
$this->client->setAuth($username, $password);
}
}

public function amOnUrl($url): void
public function amOnUrl(string $url): void
{
$host = Uri::retrieveHost($url);
$config = $this->config;
Expand All @@ -175,7 +177,7 @@ public function amOnUrl($url): void
$this->amOnPage($page);
}

public function amOnSubdomain($subdomain): void
public function amOnSubdomain(string $subdomain): void
{
$url = $this->config['url'];
$url = preg_replace('#(https?://)(.*\.)(.*\.)#', "$1$3", $url); // removing current subdomain
Expand Down Expand Up @@ -206,18 +208,13 @@ protected function onReconfigure()
*
* It is not recommended to use this command on a regular basis.
* If Codeception lacks important Guzzle Client methods, implement them and submit patches.
*
* @return mixed
*/
public function executeInGuzzle(Closure $function)
public function executeInGuzzle(Closure $function): mixed
{
return $function($this->guzzle);
}

/**
* @return int|string
*/
public function _getResponseCode()
public function _getResponseCode(): int|string
{
return $this->getResponseStatusCode();
}
Expand Down Expand Up @@ -245,21 +242,24 @@ public function _prepareSession(): void

$defaults['base_uri'] = $this->config['url'];
$defaults['curl'] = $curlOptions;
$handler = Guzzle::createHandler($this->config['handler']);
if ($handler && is_array($this->config['middleware'])) {
$handlerStack = Guzzle::createHandler($this->config['handler']);
if (is_array($this->config['middleware'])) {
foreach ($this->config['middleware'] as $middleware) {
$handler->push($middleware);
$handlerStack->push($middleware);
}
}

$defaults['handler'] = $handler;
$defaults['handler'] = $handlerStack;
$this->guzzle = new GuzzleClient($defaults);

$this->client->setRefreshMaxInterval($this->config['refresh_max_interval']);
$this->client->setClient($this->guzzle);
}

public function _backupSession(): array
/**
* @return array<string, mixed>
*/
public function _backupSession()
{
return [
'client' => $this->client,
Expand All @@ -269,13 +269,19 @@ public function _backupSession(): array
];
}

/**
* @param array<string, mixed> $session
*/
public function _loadSession($session): void
{
foreach ($session as $key => $val) {
$this->$key = $val;
}
}

/**
* @param ?array<string, mixed> $session
*/
public function _closeSession($session = null): void
{
unset($session);
Expand Down
1 change: 0 additions & 1 deletion tests/_support/UnitTester.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php


/**
* Inherited Methods
* @method void wantToTest($text)
Expand Down
Loading