Skip to content

Completely remove assertions against Swagger schema in InMemoryMagento #8

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 1 commit into from
Sep 20, 2023
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
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"amphp/artax": "^3.0",
"nikic/fast-route": "^1.3",
"webmozart/assert": "^1.4",
"fr3d/swagger-assertions": "^1.0.0",
"amphp/byte-stream": "^1.6",
"amphp/file": "^0.3",
"amphp/uri": "^0.1",
Expand Down
13 changes: 3 additions & 10 deletions src/InMemoryMagento/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -588,11 +588,8 @@ public static function putProductsHandler(Request $request, array $uriParams): R
* @return ResponseStub
* @throws \Throwable
*/
public static function postProductsAttributesOptionsHandler(
Request $request,
array $uriParams,
string $mageVersion
): ResponseStub {
public static function postProductsAttributesOptionsHandler(Request $request, array $uriParams): ResponseStub
{
if ($request->getHeader('Authorization') !== sprintf('Bearer %s', self::$accessToken)) {
return new ResponseStub(401, json_encode(['message' => 'Unauthorized.']));
}
Expand Down Expand Up @@ -630,11 +627,7 @@ public static function postProductsAttributesOptionsHandler(
}
}

$responseBody = true;
if ($mageVersion !== '2.2') {
$responseBody = sprintf('id_%s', $option->value);
}
$response = new ResponseStub(200, json_encode($responseBody));
$response = new ResponseStub(200, json_encode(true));
}

return $response;
Expand Down
141 changes: 3 additions & 138 deletions src/InMemoryMagento/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,11 @@
use Amp\Artax\HttpException;
use Amp\Artax\Request;
use Amp\Artax\Response;
use Amp\Promise;
use FastRoute;
use FastRoute\Dispatcher\GroupCountBased;
use FR3D\SwaggerAssertions\JsonSchema\RefResolver;
use FR3D\SwaggerAssertions\PhpUnit\AssertsTrait;
use FR3D\SwaggerAssertions\SchemaManager;
use JsonSchema\Constraints\Factory;
use PHPUnit\Framework\ExpectationFailedException;

final class Server
{
use AssertsTrait;
use Utils;

/** @var array */
Expand All @@ -32,28 +25,10 @@ final class Server
/**
* Server constructor.
*
* @param string|array $swaggerSchemaPaths
* @param Routes $inMemoryMagentoRoutes
*/
public function __construct($swaggerSchemaPaths, Routes $inMemoryMagentoRoutes)
public function __construct(Routes $inMemoryMagentoRoutes)
{
if (!is_array($swaggerSchemaPaths)) {
$swaggerSchemaPaths = ['all' => $swaggerSchemaPaths];
}

array_walk(
$swaggerSchemaPaths,
function ($schemaPath, $storeCode) {
//It is necessary to manually resolve all refs before initializing the SchemaManager, otherwise
//infinite loops result in case of circular references
$factory = new Factory();
$storage = $factory->getSchemaStorage();
$storage->addSchema('temp', $factory->getUriRetriever()->retrieve('file://'.$schemaPath));
$this->schema[$storeCode] = new SchemaManager($storage->getSchema('temp'));
}
);

$this->mageVersion = $this->getMageVersionFromAnyOfTheSchemas($swaggerSchemaPaths);
$this->dispatcher = new GroupCountBased($inMemoryMagentoRoutes->getData());
}

Expand All @@ -66,30 +41,7 @@ function ($schemaPath, $storeCode) {
*/
public function processRequest($uriOrRequest): Response
{
$request = $this->normalizeRequest($uriOrRequest);

try {
$this->validateRequestAgainstSchema($request);
} catch (ExpectationFailedException $error) {
$response = new ResponseStub(
400,
json_encode(
[
'message' => $error->getMessage(),
'code' => $error->getCode(),
'trace' => $error->getTraceAsString()
]
)
);

return $response;
}

$response = $this->doProcessRequest($request);

$this->validateResponseAgainstSchema($request, $response);

return $response;
return $this->doProcessRequest($this->normalizeRequest($uriOrRequest));
}

/**
Expand Down Expand Up @@ -131,7 +83,7 @@ private function doProcessRequest(Request $request): Response
$handler = $routeInfo[1];
$vars = $routeInfo[2];

return $handler($request, $vars, $this->mageVersion);
return $handler($request, $vars);
}

/**
Expand All @@ -151,91 +103,4 @@ private function normalizeRequest($uriOrRequest): Request
'Request must be a valid HTTP URI or Amp\Artax\Request instance'
);
}

/**
* @param Request $request
*
* @throws \Throwable
*/
private function validateRequestAgainstSchema(Request $request): void
{
$uri = self::buildUriFromString($request->getUri());

// check if we have in our schema /rest/[store-code]/V1
// @TODO: maybe we need a better solution
$storeCode = explode("/", $uri->getPath());
$storeCode = $storeCode[2];

if (!isset($this->schema[$storeCode])) {
return;
}

$this->assertRequestHeadersMatch(
$request->getHeaders(),
$this->schema[$storeCode],
$uri->getPath(),
$request->getMethod()
);
$this->assertRequestQueryMatch(
$uri->getAllQueryParameters(),
$this->schema[$storeCode],
$uri->getPath(),
$request->getMethod()
);
if (in_array(strtoupper($request->getMethod()), ['PUT', 'POST'])) {
$this->assertRequestBodyMatch(
self::readDecodedRequestBody($request),
$this->schema[$storeCode],
$uri->getPath(),
$request->getMethod()
);
}
}

/**
* @param Request $request
* @param Response $response
*
* @throws \Throwable
*/
private function validateResponseAgainstSchema(Request $request, Response $response): void
{
$uri = self::buildUriFromString($request->getUri());

// check if we have in our schema /rest/[store-code]/V1
// @TODO: maybe we need a better solution
$storeCode = explode("/", $uri->getPath());
$storeCode = $storeCode[2];

if (!isset($this->schema[$storeCode])) {
return;
}

$responseStatus = $response->getStatus();
$responseBody = Promise\wait($response->getBody()->read());
$this->assertResponseHeadersMatch(
$response->getHeaders(),
$this->schema[$storeCode],
$uri->getPath(),
$request->getMethod(),
$responseStatus
);
$this->assertResponseBodyMatch(
json_decode($responseBody, false),
$this->schema[$storeCode],
$uri->getPath(),
$request->getMethod(),
$responseStatus
);
}

/**
* @param array $swaggerSchemaPaths
* @return string
*/
private function getMageVersionFromAnyOfTheSchemas($swaggerSchemaPaths)
{
$anySwaggerSchema = json_decode(file_get_contents(array_values($swaggerSchemaPaths)[0]), false);
return $anySwaggerSchema->info->version;
}
}
6 changes: 2 additions & 4 deletions tests/ApiClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class ApiClientTest extends TestCase
{
use Utils;

public const MAGENTO_SCHEMA_JSON_FILE = __DIR__ . '/mage24-schema.json';

/** @var ApiClient */
private $client;

Expand All @@ -26,7 +24,7 @@ public function setUp(): void
'username' => 'admin',
'password' => 'password123'
];
$inMemoryMagento = new Server(realpath(self::MAGENTO_SCHEMA_JSON_FILE), new Routes());
$inMemoryMagento = new Server(new Routes());
$fakeClient = new HttpClient($inMemoryMagento);
$this->client = new ApiClient($fakeClient, $config);
}
Expand Down Expand Up @@ -1371,7 +1369,7 @@ public function testRequestWithAccessToken()
'baseUrl' => 'http://my-url',
'accessToken' => 'access-token-for-esb-integration',
];
$inMemoryMagento = new Server(realpath(self::MAGENTO_SCHEMA_JSON_FILE), new Routes());
$inMemoryMagento = new Server(new Routes());
$fakeClient = new HttpClient($inMemoryMagento);
$client = new ApiClient($fakeClient, $configWithAccessToken);

Expand Down
1 change: 0 additions & 1 deletion tests/mage22-schema.json

This file was deleted.

1 change: 0 additions & 1 deletion tests/mage24-schema.json

This file was deleted.