Skip to content
Prev Previous commit
Next Next commit
[Slim4] Add ref support to mockArray method
  • Loading branch information
ybelenko committed Jan 8, 2020
commit 3beaef28eb5131812a2cad3669f7eb2b2a2e97ea
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
namespace {{mockPackage}};

use {{mockPackage}}\{{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}} as IMocker;
use {{utilsPackage}}\{{traitNamePrefix}}ModelUtils{{traitNameSuffix}};
use StdClass;
use InvalidArgumentException;

Expand All @@ -46,6 +47,8 @@ use InvalidArgumentException;
*/
final class OpenApiDataMocker implements IMocker
{
use {{traitNamePrefix}}ModelUtils{{traitNameSuffix}};

/**
* Mocks OpenApi Data.
* @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#data-types
Expand Down Expand Up @@ -276,11 +279,26 @@ final class OpenApiDataMocker implements IMocker
$options = $this->extractSchemaProperties($items);
$dataType = $options['type'];
$dataFormat = $options['format'] ?? null;
$ref = $options['$ref'] ?? null;

// always genarate smallest possible array to avoid huge JSON responses
// always generate smallest possible array to avoid huge JSON responses
$arrSize = ($maxSize < 1) ? $maxSize : max($minSize, 1);
while (count($arr) < $arrSize) {
$arr[] = $this->mock($dataType, $dataFormat, $options);
if (is_string($ref) && !empty($ref)) {
$refName = static::getSimpleRef($ref);
$modelName = static::toModelName($refName);
$modelClass = '{{modelPackage}}\\' . $modelName;
if (!class_exists($modelClass) || !method_exists($modelClass, 'getOpenApiSchema')) {
throw new InvalidArgumentException(sprintf(
'Model %s not found or method %s doesn\'t exist',
$modelClass,
$modelClass . '::getOpenApiSchema'
));
}
$arr[] = $this->mockFromSchema($modelClass::getOpenApiSchema());
} else {
$arr[] = $this->mock($dataType, $dataFormat, $options);
}
}
return $arr;
}
Expand Down Expand Up @@ -420,6 +438,7 @@ final class OpenApiDataMocker implements IMocker
'additionalProperties',
'required',
'example',
'$ref',
] as $propName
) {
if (is_array($val) && array_key_exists($propName, $val)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,9 +648,33 @@ class OpenApiDataMockerTest extends TestCase
'maxItems less than minItems' => [
$intItems, 5, 2, false,
],
'items with ref to unknown class' => [
['$ref' => '#/components/schemas/UnknownClass'], null, null, false,
],
'items with ref to class without getOpenApiSchema method' => [
['$ref' => '#/components/schemas/ClassWithoutGetSchemaMethod'], null, null, false,
],
];
}

/**
* @covers ::mockArray
*/
public function testMockArrayWithRef()
{
$mocker = new OpenApiDataMocker();
$arr = $mocker->mockArray(['$ref' => '#/components/schemas/CatRefTestClass']);
$this->assertIsArray($arr);
$this->assertCount(1, $arr);
foreach ($arr as $item) {
// TODO: replace with assertInstanceOf assertion
$this->assertInternalType(IsType::TYPE_OBJECT, $item);
$this->assertInternalType(IsType::TYPE_STRING, $item->className);
$this->assertInternalType(IsType::TYPE_STRING, $item->color);
$this->assertInternalType(IsType::TYPE_BOOL, $item->declawed);
}
}

/**
* @dataProvider provideMockObjectCorrectArguments
* @covers ::mockObject
Expand Down Expand Up @@ -883,4 +907,41 @@ class OpenApiDataMockerTest extends TestCase
];
}
}

namespace {{modelPackage}};

// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
final class CatRefTestClass
{
private const MODEL_SCHEMA = <<<'SCHEMA'
{
"required" : [ "className" ],
"type" : "object",
"properties" : {
"className" : {
"type" : "string"
},
"color" : {
"type" : "string",
"default" : "red"
},
"declawed" : {
"type" : "boolean"
}
},
"discriminator" : {
"propertyName" : "className"
}
}
SCHEMA;

public static function getOpenApiSchema()
{
return json_decode(static::MODEL_SCHEMA, true);
}
}

final class ClassWithoutGetSchemaMethod
{
}
{{/apiInfo}}