v1.3.0 #11

Merged
anthony merged 1 commits from dev into master 2023-09-10 01:12:38 +00:00
26 changed files with 2901 additions and 300 deletions
Showing only changes of commit 1345b7eddb - Show all commits

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
/.idea /.idea
/.vscode /.vscode
/vendor /vendor
.phpunit.result.cache
.phpunit.cache

View File

@ -90,13 +90,24 @@ Example:
--env ~/localhost.postman_environment.json \ --env ~/localhost.postman_environment.json \
-d ~/personal \ -d ~/personal \
-o ~/postman_export -o ~/postman_export
``` ```
### Notice
Make sure every (I mean _every_) collection (not collection file), its folders and/or requests has unique names. ### Notices
If not, you can rename them in Postman or convert collections with similar names into different directories.
Otherwise converted files may be overwritten by each other. 1. Result of `pm-convert` execution is bunch of generated files.
Most likely they will contain errors such as not interpolated `{{variables}}` values (due to missed ones in collection),
wrong command format or `GET`s with bodies.
You must review any generated file before using.
2. Make sure every (I mean _every_) collection (not collection file), its folders and/or requests has unique names.
If not, you can rename them in Postman or convert collections with similar names into different directories.
Otherwise any generated file may be accidently overwritten by another one.
## How to implement a new format
1. Create new namespace in `./src/Converters` and name it according to format of your choice
2. Create two classes for converter and request object which extends `Converters\Abstract\Abstract{Converter, Request}` respectively
3. Change constants values in your new request class according to format you want to implement
4. Write your own logic in converter's `__toString()` method, write new methods and override abstract ones
## License ## License

View File

@ -15,9 +15,7 @@
"php": "^8.1", "php": "^8.1",
"ext-json": "*" "ext-json": "*"
}, },
"bin": [ "bin": ["pm-convert"],
"pm-convert"
],
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"PmConverter\\": "src\\" "PmConverter\\": "src\\"
@ -30,5 +28,8 @@
"optimize-autoloader": true, "optimize-autoloader": true,
"preferred-install": "dist", "preferred-install": "dist",
"sort-packages": true "sort-packages": true
},
"require-dev": {
"phpunit/phpunit": "^10.3"
} }
} }

1614
composer.lock generated

File diff suppressed because it is too large Load Diff

26
phpunit.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="Main">
<!-- <directory>tests</directory>-->
<file>tests/AbstractRequestTest.php</file>
<file>tests/HttpRequestTest.php</file>
<file>tests/WgetRequestTest.php</file>
</testsuite>
</testsuites>
<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
<include>
<directory>src</directory>
</include>
</source>
</phpunit>

View File

@ -2,13 +2,14 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Abstract; namespace PmConverter\Converters\Abstract;
use Exception; use Exception;
use PmConverter\Environment; use PmConverter\Converters\{
use PmConverter\Exporters\{
ConverterContract, ConverterContract,
RequestContract}; RequestContract};
use PmConverter\Environment;
use PmConverter\Exceptions\InvalidHttpVersionException;
use PmConverter\FileSystem; use PmConverter\FileSystem;
/** /**
@ -129,14 +130,16 @@ abstract class AbstractConverter implements ConverterContract
* *
* @param object $item * @param object $item
* @return RequestContract * @return RequestContract
* @throws InvalidHttpVersionException
*/ */
protected function initRequest(object $item): RequestContract protected function initRequest(object $item): RequestContract
{ {
$request_class = static::REQUEST_CLASS; $request_class = static::REQUEST_CLASS;
/** @var RequestContract $result */ /** @var RequestContract $result */
$result = new $request_class($this->vars); $result = new $request_class();
$result->setName($item->name); $result->setName($item->name);
$result->setHttpVersion(1.1); //TODO http version?
$result->setDescription($item->request?->description ?? null); $result->setDescription($item->request?->description ?? null);
$result->setVerb($item->request->method); $result->setVerb($item->request->method);
$result->setUrl($item->request->url->raw); $result->setUrl($item->request->url->raw);

View File

@ -0,0 +1,295 @@
<?php
declare(strict_types=1);
namespace PmConverter\Converters\Abstract;
use PmConverter\Converters\RequestContract;
use PmConverter\Exceptions\{
EmptyHttpVerbException,
InvalidHttpVersionException};
use PmConverter\HttpVersions;
use Stringable;
/**
* Class to determine file content with any request format
*/
abstract class AbstractRequest implements Stringable, RequestContract
{
/**
* @var string HTTP verb (GET, POST, etc.)
*/
protected string $verb;
/**
* @var string URL where to send a request
*/
protected string $url;
/**
* @var float HTTP protocol version
*/
protected float $httpVersion = 1.1;
/**
* @var string Request name
*/
protected string $name;
/**
* @var string|null Request description
*/
protected ?string $description = null;
/**
* @var array Request headers
*/
protected array $headers = [];
/**
* @var mixed Request body
*/
protected mixed $body = null;
/**
* @var string Request body type
*/
protected string $bodymode = 'raw';
/**
* @inheritDoc
*/
public function setHttpVersion(float $version): static
{
if (!in_array($version, HttpVersions::values())) {
throw new InvalidHttpVersionException(
'Only these HTTP versions are supported: ' . implode(', ', HttpVersions::values())
);
}
$this->httpVersion = $version;
return $this;
}
/**
* @inheritDoc
*/
public function getHttpVersion(): float
{
return $this->httpVersion;
}
/**
* @inheritDoc
*/
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
/**
* @inheritDoc
*/
public function getName(): string
{
return str_replace(DIRECTORY_SEPARATOR, '_', $this->name);
}
/**
* @inheritDoc
*/
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
/**
* @inheritDoc
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @inheritDoc
*/
public function setVerb(string $verb): static
{
$this->verb = $verb;
return $this;
}
/**
* @inheritDoc
*/
public function getVerb(): string
{
empty($this->verb) && throw new EmptyHttpVerbException('Request HTTP verb must be defined before conversion');
return $this->verb;
}
/**
* @inheritDoc
*/
public function setUrl(string $url): static
{
$this->url = $url;
return $this;
}
/**
* @inheritDoc
*/
public function getUrl(): string
{
return $this->url ?: '<empty url>';
}
/**
* @inheritDoc
*/
public function setHeaders(?array $headers): static
{
foreach ($headers as $header) {
$this->setHeader($header->key, $header->value, $header?->disabled ?? false);
}
return $this;
}
/**
* @inheritDoc
*/
public function setHeader(string $name, mixed $value, bool $disabled = false): static
{
$this->headers[$name] = [
'value' => $value,
'disabled' => $disabled,
];
return $this;
}
/**
* @inheritDoc
*/
public function getHeaders(): array
{
return $this->headers;
}
/**
* @inheritDoc
*/
public function setAuth(?object $auth): static
{
if (!empty($auth)) {
switch ($auth->type) {
case 'bearer':
$this->setHeader('Authorization', 'Bearer ' . $auth->{$auth->type}[0]->value);
break;
default:
break;
}
}
return $this;
}
/**
* @inheritDoc
*/
public function setBodymode(string $bodymode): static
{
$this->bodymode = $bodymode;
return $this;
}
/**
* @inheritDoc
*/
public function getBodymode(): string
{
return $this->bodymode;
}
/**
* @inheritDoc
*/
public function setBody(object $body): static
{
$this->setBodymode($body->mode);
if ($body->mode === 'formdata') {
$this->setHeader('Content-Type', 'multipart/form-data')
->setFormdataBody($body);
} elseif (!empty($body->options) && $body->options->{$this->bodymode}->language === 'json') {
$this->setHeader('Content-Type', 'application/json')
->setJsonBody($body);
}
return $this;
}
/**
* Sets body content from multipart/formdata
*
* @param object $body
* @return $this
*/
protected function setFormdataBody(object $body): static
{
foreach ($body->formdata as $field) {
$this->body[$field->key] = [
'value' => $field->type === 'file' ? $field->src : $field->value,
'type' => $field->type,
];
}
return $this;
}
/**
* Sets body content from application/json
*
* @param object $body
* @return $this
*/
protected function setJsonBody(object $body): static
{
$this->body = $body->{$this->getBodymode()};
return $this;
}
/**
* @inheritDoc
*/
public function getBody(): mixed
{
return $this->body;
}
/**
* Returns array of description lines
*
* @return array
*/
abstract protected function prepareDescription(): array;
/**
* Returns array of headers
*
* @return array
*/
abstract protected function prepareHeaders(): array;
/**
* Returns array of request body lines
*
* @return array
*/
abstract protected function prepareBody(): array;
/**
* Converts request object to string to be written in result file
*
* @return string
*/
abstract public function __toString(): string;
}

View File

@ -2,12 +2,13 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters; namespace PmConverter\Converters;
use PmConverter\Exporters\Curl\CurlConverter; use PmConverter\Converters\{
use PmConverter\Exporters\Http\HttpConverter; Curl\CurlConverter,
use PmConverter\Exporters\Wget\WgetConverter; Http\HttpConverter,
Wget\WgetConverter};
enum ConvertFormat: string enum ConvertFormat: string
{ {

View File

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters; namespace PmConverter\Converters;
interface ConverterContract interface ConverterContract
{ {

View File

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Curl; namespace PmConverter\Converters\Curl;
use PmConverter\Exporters\{ use PmConverter\Converters\{
Abstract\AbstractConverter, Abstract\AbstractConverter,
ConverterContract}; ConverterContract};

View File

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Curl; namespace PmConverter\Converters\Curl;
use PmConverter\Exporters\Abstract\AbstractRequest; use PmConverter\Converters\Abstract\AbstractRequest;
/** /**
* Class to determine file content with curl request format * Class to determine file content with curl request format
@ -31,7 +31,7 @@ class CurlRequest extends AbstractRequest
if ($header['disabled']) { if ($header['disabled']) {
continue; continue;
} }
$output[] = sprintf("\t--header '%s=%s' \ ", $header_key, $header['value']); $output[] = sprintf("\t--header '%s: %s' \ ", $header_key, $header['value']);
} }
return $output; return $output;
} }
@ -44,12 +44,12 @@ class CurlRequest extends AbstractRequest
$output = []; $output = [];
switch ($this->bodymode) { switch ($this->bodymode) {
case 'formdata': case 'formdata':
foreach ($this->body as $data) { foreach ($this->body as $key => $data) {
$output[] = sprintf( $output[] = sprintf(
"%s\t--form '%s=%s' \ ", "%s\t--form '%s=%s' \ ",
isset($data->disabled) ? '# ' : '', isset($data['disabled']) ? '# ' : '',
$data->key, $key,
$data->type === 'file' ? "@$data->src" : $data->value $data['type'] === 'file' ? "@" . $data['value'] : $data['value']
); );
} }
break; break;

View File

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Http; namespace PmConverter\Converters\Http;
use PmConverter\Exporters\{ use PmConverter\Converters\{
Abstract\AbstractConverter, Abstract\AbstractConverter,
ConverterContract}; ConverterContract};

View File

@ -2,9 +2,11 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Http; namespace PmConverter\Converters\Http;
use PmConverter\Exporters\Abstract\AbstractRequest; use PmConverter\Converters\Abstract\AbstractRequest;
use PmConverter\Exceptions\{
EmptyHttpVerbException};
/** /**
* Class to determine file content with http request format * Class to determine file content with http request format
@ -23,12 +25,13 @@ class HttpRequest extends AbstractRequest
/** /**
* @inheritDoc * @inheritDoc
* @throws EmptyHttpVerbException
*/ */
protected function prepareHeaders(): array protected function prepareHeaders(): array
{ {
$output[] = "$this->verb $this->url $this->http"; $output[] = sprintf('%s %s HTTP/%s', $this->getVerb(), $this->getUrl(), $this->getHttpVersion());
foreach ($this->headers as $header_key => $header) { foreach ($this->headers as $name => $data) {
$output[] = sprintf('%s%s: %s', $header['disabled'] ? '# ' : '', $header_key, $header['value']); $output[] = sprintf('%s%s: %s', $data['disabled'] ? '# ' : '', $name, $data['value']);
} }
return $output; return $output;
} }
@ -38,15 +41,15 @@ class HttpRequest extends AbstractRequest
*/ */
protected function prepareBody(): array protected function prepareBody(): array
{ {
switch ($this->bodymode) { switch ($this->getBodymode()) {
case 'formdata': case 'formdata':
$output = ['']; $output = [''];
foreach ($this->body as $data) { foreach ($this->body as $key => $data) {
$output[] = sprintf( $output[] = sprintf(
'%s%s=%s', '%s%s=%s',
empty($data->disabled) ? '' : '# ', empty($data['disabled']) ? '' : '# ',
$data->key, $key,
$data->type === 'file' ? $data->src : $data->value $data['type'] === 'file' ? '@' . $data['value'] : $data['value']
); );
} }
return $output; return $output;
@ -57,6 +60,7 @@ class HttpRequest extends AbstractRequest
/** /**
* @inheritDoc * @inheritDoc
* @throws EmptyHttpVerbException
*/ */
public function __toString(): string public function __toString(): string
{ {

View File

@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace PmConverter\Converters;
use PmConverter\Converters\Http\HttpRequest;
use PmConverter\Exceptions\{
EmptyHttpVerbException,
InvalidHttpVersionException};
interface RequestContract
{
/**
* Sets HTTP protocol version
*
* @param float $version
* @return $this
* @throws InvalidHttpVersionException
*/
public function setHttpVersion(float $version): static;
/**
* Returns HTTP protocol version
*
* @return float
*/
public function getHttpVersion(): float;
/**
* Sets name from collection item to request object
*
* @param string $name
* @return HttpRequest
*/
public function setName(string $name): static;
/**
* Returns name of request
*
* @return string
*/
public function getName(): string;
/**
* Sets description from collection item to request object
*
* @param string|null $description
* @return HttpRequest
*/
public function setDescription(?string $description): static;
/**
* Returns description request
*
* @return string|null
*/
public function getDescription(): ?string;
/**
* Sets HTTP verb from collection item to request object
*
* @param string $verb
* @return HttpRequest
*/
public function setVerb(string $verb): static;
/**
* Returns HTTP verb of request
*
* @return string
* @throws EmptyHttpVerbException
*/
public function getVerb(): string;
/**
* Sets URL from collection item to request object
*
* @param string $url
* @return HttpRequest
*/
public function setUrl(string $url): static;
/**
* Returns URL of request
*
* @return string
*/
public function getUrl(): string;
/**
* Sets headers from collection item to request object
*
* @param object[]|null $headers
* @return $this
*/
public function setHeaders(?array $headers): static;
/**
* Sets one header to request object
*
* @param string $name Header's name
* @param mixed $value Header's value
* @param bool $disabled Pass true to skip (or comment out) this header
* @return $this
*/
public function setHeader(string $name, mixed $value, bool $disabled = false): static;
/**
* Returns array of prepared headers
*
* @return array
*/
public function getHeaders(): array;
/**
* Sets authorization headers
*
* @param object|null $auth
* @return $this
*/
public function setAuth(object $auth): static;
/**
* Sets body mode from collection item to request object
*
* @param string $bodymode
* @return HttpRequest
*/
public function setBodymode(string $bodymode): static;
/**
* Returns body mode of request
*
* @return HttpRequest
*/
public function getBodymode(): string;
/**
* Sets body from collection item to request object
*
* @param object $body
* @return $this
*/
public function setBody(object $body): static;
/**
* Returns body content
*
* @return mixed
*/
public function getBody(): mixed;
}

View File

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Wget; namespace PmConverter\Converters\Wget;
use PmConverter\Exporters\{ use PmConverter\Converters\{
Abstract\AbstractConverter, Abstract\AbstractConverter,
ConverterContract}; ConverterContract};

View File

@ -2,9 +2,10 @@
declare(strict_types=1); declare(strict_types=1);
namespace PmConverter\Exporters\Wget; namespace PmConverter\Converters\Wget;
use PmConverter\Exporters\Abstract\AbstractRequest; use PmConverter\Converters\Abstract\AbstractRequest;
use PmConverter\Exceptions\EmptyHttpVerbException;
/** /**
* Class to determine file content with wget request format * Class to determine file content with wget request format
@ -31,7 +32,7 @@ class WgetRequest extends AbstractRequest
if ($header['disabled']) { if ($header['disabled']) {
continue; continue;
} }
$output[] = sprintf("\t--header '%s=%s' \ ", $header_key, $header['value']); $output[] = sprintf("\t--header '%s: %s' \ ", $header_key, $header['value']);
} }
return $output; return $output;
} }
@ -43,22 +44,22 @@ class WgetRequest extends AbstractRequest
{ {
switch ($this->bodymode) { switch ($this->bodymode) {
case 'formdata': case 'formdata':
$params = []; $output = [];
foreach ($this->body as $data) { foreach ($this->body as $key => $data) {
if ($data->type === 'file') { if ($data['type'] === 'file') {
continue; continue;
} }
$params[$data->key] = $data->value; $output[$key] = $data['value'];
} }
$output[] = http_build_query($params);
return $output; return $output;
default: default:
return ["\t'$this->body' \ "]; return [$this->body];
} }
} }
/** /**
* @inheritDoc * @inheritDoc
* @throws EmptyHttpVerbException
*/ */
public function __toString(): string public function __toString(): string
{ {
@ -68,14 +69,26 @@ class WgetRequest extends AbstractRequest
[ [
'wget \ ', 'wget \ ',
"\t--no-check-certificate \ ", "\t--no-check-certificate \ ",
"\t--quiet \ ", "\t--timeout 0 \ ",
"\t--timeout=0 \ ",
"\t--method $this->verb \ ", "\t--method $this->verb \ ",
], ],
$this->prepareHeaders(), $this->prepareHeaders(),
$this->prepareBody()
); );
$output[] = "\t'$this->url'"; if ($this->getBodymode() === 'formdata') {
if ($this->getBody()) {
if ($this->getVerb() === 'GET') {
$output[] = sprintf("\t%s?%s", $this->getUrl(), http_build_query($this->prepareBody()));
} else {
$output[] = sprintf("\t--body-data '%s' \ ", http_build_query($this->prepareBody()));
$output[] = sprintf("\t%s", $this->getUrl());
}
}
} else {
if ($this->getVerb() !== 'GET') {
$output[] = sprintf("\t--body-data '%s' \ ", implode("\n", $this->prepareBody()));
$output[] = sprintf("\t%s", $this->getUrl());
}
}
return implode(PHP_EOL, array_merge($output, [''])); return implode(PHP_EOL, array_merge($output, ['']));
} }
} }

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exceptions;
use Exception;
class EmptyHttpVerbException extends Exception
{
}

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exceptions;
use Exception;
class EmptyURLException extends Exception
{
}

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exceptions;
use Exception;
class InvalidHttpVersionException extends Exception
{
}

View File

@ -1,222 +0,0 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Abstract;
use PmConverter\Exporters\Http\HttpRequest;
use PmConverter\Exporters\RequestContract;
/**
* Class to determine file content with any request format
*/
abstract class AbstractRequest implements RequestContract
{
/**
* @var string
*/
protected string $http = 'HTTP/1.1'; //TODO proto
/**
* @var string
*/
protected string $name;
/**
* @var string|null
*/
protected ?string $description = null;
/**
* @var array
*/
protected array $headers = [];
/**
* @var mixed
*/
protected mixed $body = null;
/**
* @var string
*/
protected string $bodymode = 'raw';
/**
* @var string
*/
protected string $verb;
/**
* @var string
*/
protected string $url;
/**
* Sets name from collection item to request object
*
* @param string $name
* @return HttpRequest
*/
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
/**
* Returns name of request
*
* @return string
*/
public function getName(): string
{
return str_replace(DIRECTORY_SEPARATOR, '_', $this->name);
}
/**
* Sets description from collection item to request object
*
* @param string|null $description
* @return HttpRequest
*/
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
/**
* Sets HTTP verb from collection item to request object
*
* @param string $verb
* @return HttpRequest
*/
public function setVerb(string $verb): static
{
$this->verb = $verb;
return $this;
}
/**
* Sets URL from collection item to request object
*
* @param string $url
* @return HttpRequest
*/
public function setUrl(string $url): static
{
$this->url = $url;
return $this;
}
/**
* Sets headers from collection item to request object
*
* @param object[]|null $headers
* @return $this
*/
public function setHeaders(?array $headers): static
{
foreach ($headers as $header) {
$this->headers[$header->key] = [
'value' => $header->value,
'disabled' => $header?->disabled ?? false,
];
}
return $this;
}
/**
* Sets authorization headers
*
* @param object|null $auth
* @return $this
*/
public function setAuth(?object $auth): static
{
if (!empty($auth)) {
switch ($auth->type) {
case 'bearer':
$this->headers['Authorization'] = [
'value' => 'Bearer ' . $auth->{$auth->type}[0]->value,
'disabled' => false,
];
break;
default:
break;
}
}
return $this;
}
/**
* Sets body mode from collection item to request object
*
* @param string $bodymode
* @return HttpRequest
*/
public function setBodymode(string $bodymode): static
{
$this->bodymode = $bodymode;
return $this;
}
/**
* Sets body from collection item to request object
*
* @param object $body
* @return $this
*/
public function setBody(object $body): static
{
$this->setBodymode($body->mode);
if (!empty($body->options) && $body->options->{$this->bodymode}->language === 'json') {
empty($this->headers['Content-Type']) && $this->setHeaders([
(object)[
'key' => 'Content-Type',
'value' => 'application/json',
'disabled' => false,
],
]);
}
$body->mode === 'formdata' && $this->setHeaders([
(object)[
'key' => 'Content-Type',
'value' => 'multipart/form-data',
'disabled' => false,
],
]);
$this->body = $body->{$body->mode};
return $this;
}
/**
* Returns array of description lines
*
* @return array
*/
abstract protected function prepareDescription(): array;
/**
* Returns array of headers
*
* @return array
*/
abstract protected function prepareHeaders(): array;
/**
* Returns array of request body lines
*
* @return array
*/
abstract protected function prepareBody(): array;
/**
* Converts request object to string to be written in result file
*
* @return string
*/
abstract public function __toString(): string;
}

View File

@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters;
interface RequestContract
{
public function setName(string $name): static;
public function getName(): string;
public function setDescription(?string $description): static;
public function setVerb(string $verb): static;
public function setUrl(string $url): static;
public function setAuth(object $auth): static;
public function setHeaders(?array $headers): static;
public function setBodymode(string $bodymode): static;
public function setBody(object $body): static;
public function __toString(): string;
}

21
src/HttpVersions.php Normal file
View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace PmConverter;
enum HttpVersions: string
{
case Version10 = '1.0';
case Version11 = '1.1';
case Version2 = '2';
case Version3 = '3';
public static function values(): array
{
return array_combine(
array_column(self::cases(), 'name'),
array_column(self::cases(), 'value'),
);
}
}

View File

@ -7,14 +7,14 @@ namespace PmConverter;
use Exception; use Exception;
use InvalidArgumentException; use InvalidArgumentException;
use JsonException; use JsonException;
use PmConverter\Converters\{
ConverterContract,
ConvertFormat};
use PmConverter\Exceptions\{ use PmConverter\Exceptions\{
CannotCreateDirectoryException, CannotCreateDirectoryException,
DirectoryIsNotReadableException, DirectoryIsNotReadableException,
DirectoryIsNotWriteableException, DirectoryIsNotWriteableException,
DirectoryNotExistsException}; DirectoryNotExistsException};
use PmConverter\Exporters\{
ConverterContract,
ConvertFormat};
class Processor class Processor
{ {

View File

@ -0,0 +1,297 @@
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use PmConverter\Exceptions\{
EmptyHttpVerbException,
InvalidHttpVersionException};
class AbstractRequestTest extends TestCase
{
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\HttpVersions
* @return void
* @throws InvalidHttpVersionException
*/
public function testHttpVersion(): void
{
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setHttpVersion(2.0);
$this->assertSame(2.0, $request->getHttpVersion());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
* @covers PmConverter\HttpVersions
* @return void
* @throws InvalidHttpVersionException
*/
public function testInvalidHttpVersionException(): void
{
$this->expectException(InvalidHttpVersionException::class);
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setHttpVersion(5);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setVerb()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
* @return void
* @throws EmptyHttpVerbException
*/
public function testVerb(): void
{
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setVerb('GET');
$this->assertSame('GET', $request->getVerb());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
* @return void
* @throws EmptyHttpVerbException
*/
public function testEmptyHttpVerbException(): void
{
$this->expectException(EmptyHttpVerbException::class);
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->getVerb();
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setUrl()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getUrl()
* @return void
*/
public function testUrl(): void
{
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setUrl('http://localhost');
$this->assertSame('http://localhost', $request->getUrl());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setName()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getName()
* @return void
*/
public function testName(): void
{
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setName('lorem ipsum');
$this->assertSame('lorem ipsum', $request->getName());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setDescription()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getDescription()
* @return void
*/
public function testDescription(): void
{
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setDescription("lorem ipsum\ndolor sit\namet");
$this->assertSame("lorem ipsum\ndolor sit\namet", $request->getDescription());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodymode()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getBodymode()
* @return void
*/
public function testBodyMode(): void
{
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setBodymode('raw');
$this->assertSame('raw', $request->getBodymode());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeaders()
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeader()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getHeaders()
* @return void
*/
public function testHeaders(): void
{
$headers = [
(object)[
'key' => 'Header 1',
'value' => 'Value 1',
'disabled' => true,
],
(object)[
'key' => 'Header 2',
'value' => 'Value 2',
'disabled' => false,
],
(object)[
'key' => 'Header 3',
'value' => 'Value 3',
],
];
$expected = [
'Header 1' => [
'value' => 'Value 1',
'disabled' => true,
],
'Header 2' => [
'value' => 'Value 2',
'disabled' => false,
],
'Header 3' => [
'value' => 'Value 3',
'disabled' => false,
],
'Header 4' => [
'value' => 'Value 4',
'disabled' => false,
],
'Header 5' => [
'value' => 'Value 5',
'disabled' => true,
],
];
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setHeaders($headers)
->setHeader('Header 4', 'Value 4')
->setHeader('Header 5', 'Value 5', true);
$this->assertSame($expected, $request->getHeaders());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setAuth()
* @return void
*/
public function testAuthBearer(): void
{
$auth = (object)[
'type' => 'bearer',
'bearer' => [
(object)[
'key' => 'token',
'value' => 'qwerty',
'type' => 'string',
]
]
];
$expected = [
'Authorization' => [
'value' => 'Bearer qwerty',
'disabled' => false,
],
];
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setAuth($auth);
$this->assertSame($expected, $request->getHeaders());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodymode()
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeader()
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBody()
* @covers PmConverter\Converters\Abstract\AbstractRequest::setJsonBody()
* @covers PmConverter\Converters\Abstract\AbstractRequest::getBody()
* @return void
*/
public function testJson(): void
{
$body = (object)[
'mode' => 'raw',
'raw' => $expectedBody = '["lorem ipsum dolor sit amet"]',
'options' => (object)[
'raw' => (object)[
'language' => 'json',
]
]
];
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setBody($body);
$expectedHeaders = [
'Content-Type' => [
'value' => 'application/json',
'disabled' => false,
],
];
$this->assertSame($expectedHeaders, $request->getHeaders());
$this->assertSame($expectedBody, $request->getBody());
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodymode
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeader
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBody
* @covers PmConverter\Converters\Abstract\AbstractRequest::setFormdataBody
* @covers PmConverter\Converters\Abstract\AbstractRequest::getBody
* @return void
*/
public function testFormdata(): void
{
$body = (object)[
'mode' => 'formdata',
'formdata' => [
(object)[
'key' => 'param1',
'value' => 'value1',
'type' => 'text',
],
(object)[
'key' => 'param2',
'src' => '/tmp/somefile.txt',
'type' => 'file',
],
],
];
$expectedBody = [
'param1' => [
'value' => 'value1',
'type' => 'text',
],
'param2' => [
'value' => '/tmp/somefile.txt',
'type' => 'file',
],
];
$expectedHeaders = [
'Content-Type' => [
'value' => 'multipart/form-data',
'disabled' => false,
],
];
$request = new \PmConverter\Converters\Http\HttpRequest();
$request->setBody($body);
$this->assertSame($expectedHeaders, $request->getHeaders());
$this->assertSame($expectedBody, $request->getBody());
}
}

140
tests/HttpRequestTest.php Normal file
View File

@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use PmConverter\Converters\Http\HttpRequest;
class HttpRequestTest extends TestCase
{
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Http\HttpRequest
* @covers PmConverter\Converters\Http\HttpRequest::prepareDescription()
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
* @return void
*/
public function testPrepareDescription()
{
$description = [
'lorem ipsum',
'dolor sit',
'amet',
];
$needle = implode("\n", [
'# lorem ipsum',
'# dolor sit',
'# amet',
]);
$request = (new HttpRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setDescription(implode("\n", $description));
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Http\HttpRequest
* @covers PmConverter\Converters\Http\HttpRequest::prepareHeaders()
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
* @return void
*/
public function testPrepareHeaders()
{
$headers = [
(object)[
'key' => 'Header1',
'value' => 'Value 1',
'disabled' => true,
],
(object)[
'key' => 'Header2',
'value' => 'Value 2',
'disabled' => false,
],
(object)[
'key' => 'Header3',
'value' => 'Value 3',
],
];
$needle = implode("\n", [
'# Header1: Value 1',
'Header2: Value 2',
'Header3: Value 3',
]);
$request = (new HttpRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setHeaders($headers);
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Http\HttpRequest
* @covers PmConverter\Converters\Http\HttpRequest::prepareBody()
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
* @return void
*/
public function testPrepareFormdataBody()
{
$body = (object)[
'mode' => 'formdata',
'formdata' => [
(object)[
'key' => 'param1',
'value' => 'value1',
'type' => 'text',
],
(object)[
'key' => 'param2',
'src' => '/tmp/somefile.txt',
'type' => 'file',
],
],
];
$needle = implode("\n", [
'param1=value1',
'param2=@/tmp/somefile.txt',
]);
$request = (new HttpRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setBody($body);
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Http\HttpRequest
* @covers PmConverter\Converters\Http\HttpRequest::prepareBody()
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
* @return void
*/
public function testPrepareJsonBody()
{
$body = (object)[
'mode' => 'raw',
'raw' => $needle = '["lorem ipsum dolor sit amet"]',
'options' => (object)[
'raw' => (object)[
'language' => 'json',
]
]
];
$request = (new HttpRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setBody($body);
$this->assertStringContainsString($needle, (string)$request);
}
}

232
tests/WgetRequestTest.php Normal file
View File

@ -0,0 +1,232 @@
<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use PmConverter\Converters\Wget\WgetRequest;
class WgetRequestTest extends TestCase
{
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareDescription()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareNotEmptyDescription()
{
$request = (new WgetRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setDescription(null);
$result = explode("\n", (string)$request);
$this->assertFalse(str_starts_with($result[0], '# ') && str_starts_with($result[1], '# '));
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareDescription()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareEmptyDescription()
{
$description = [
'lorem ipsum',
'dolor sit',
'amet',
];
$needle = implode("\n", [
'# lorem ipsum',
'# dolor sit',
'# amet',
]);
$request = (new WgetRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setDescription(implode("\n", $description));
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareHeaders()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareHeaders()
{
$headers = [
(object)[
'key' => 'Header1',
'value' => 'Value 1',
'disabled' => true,
],
(object)[
'key' => 'Header2',
'value' => 'Value 2',
'disabled' => false,
],
(object)[
'key' => 'Header3',
'value' => 'Value 3',
],
];
$needle = implode("\n", [
"\t--header 'Header2: Value 2' \ ",
"\t--header 'Header3: Value 3' \ ",
]);
$request = (new WgetRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setHeaders($headers);
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareFormdataBodyGet()
{
$body = (object)[
'mode' => 'formdata',
'formdata' => [
(object)[
'key' => 'param1',
'value' => 'value1',
'type' => 'text',
],
(object)[
'key' => 'param2',
'src' => '/tmp/somefile.txt',
'type' => 'file',
],
(object)[
'key' => 'param3',
'value' => 'value3',
'type' => 'text',
],
],
];
$needle = 'http://localhost?' . http_build_query([
'param1' => 'value1',
'param3' => 'value3',
]);
$request = (new WgetRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setBody($body);
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareFormdataBodyPost()
{
$body = (object)[
'mode' => 'formdata',
'formdata' => [
(object)[
'key' => 'param1',
'value' => 'value1',
'type' => 'text',
],
(object)[
'key' => 'param2',
'src' => '/tmp/somefile.txt',
'type' => 'file',
],
(object)[
'key' => 'param3',
'value' => 'value3',
'type' => 'text',
],
],
];
$needle = http_build_query([
'param1' => 'value1',
'param3' => 'value3',
]);
$request = (new WgetRequest())
->setVerb('POST')
->setUrl('http://localhost')
->setBody($body);
$this->assertStringContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareJsonBodyGet()
{
$body = (object)[
'mode' => 'raw',
'raw' => $needle = '["lorem ipsum dolor sit amet"]',
'options' => (object)[
'raw' => (object)[
'language' => 'json',
]
]
];
$request = (new WgetRequest())
->setVerb('GET')
->setUrl('http://localhost')
->setBody($body);
$this->assertStringNotContainsString($needle, (string)$request);
}
/**
* @covers PmConverter\Converters\Abstract\AbstractRequest
* @covers PmConverter\Converters\Wget\WgetRequest
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
* @return void
*/
public function testPrepareJsonBodyPost()
{
$body = (object)[
'mode' => 'raw',
'raw' => $needle = '["lorem ipsum dolor sit amet"]',
'options' => (object)[
'raw' => (object)[
'language' => 'json',
]
]
];
$request = (new WgetRequest())
->setVerb('POST')
->setUrl('http://localhost')
->setBody($body);
$this->assertStringContainsString($needle, (string)$request);
}
}