diff --git a/.travis.yml b/.travis.yml index 2e1fe1f09..4d8c5f8af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,13 @@ language: php php: - 7.0 - 7.1 -install: - - composer install --no-interaction --prefer-source -before_script: - - composer require codacy/coverage --dev +install: composer install --no-interaction --prefer-source +env: + matrix: + - VERIFICATION_TOOL=copyright-check + - VERIFICATION_TOOL=phpunit-checks + - VERIFICATION_TOOL=static-checks script: - - bin/all-checks + - bin/$VERIFICATION_TOOL after_script: - - php vendor/bin/codacycoverage phpunit - - \ No newline at end of file + - if [ $VERIFICATION_TOOL == "phpunit-checks" ]; then php vendor/bin/codacycoverage phpunit; fi diff --git a/bin/static-checks b/bin/static-checks index e1ddd268a..cdc6b8c7b 100755 --- a/bin/static-checks +++ b/bin/static-checks @@ -3,6 +3,8 @@ echo "===============================PHP CODE SNIFFER REPORT===============================" vendor/bin/phpcs ./src --standard=./dev/tests/static/Magento +vendor/bin/phpcs ./dev/tests/unit --standard=./dev/tests/static/Magento +vendor/bin/phpcs ./dev/tests/verification --standard=./dev/tests/static/Magento echo "===============================COPY PASTE DETECTOR REPORT===============================" vendor/bin/phpcpd ./src diff --git a/composer.json b/composer.json index 427d08cbe..b98c2ef22 100755 --- a/composer.json +++ b/composer.json @@ -4,22 +4,30 @@ "description": "Magento2 Functional Testing Framework", "keywords": ["magento", "automation", "functional", "testing"], "require": { - "php": "~7.0", - "codeception/codeception": "2.2|2.3", + "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", + "codeception/codeception": "~2.3.4", "flow/jsonpath": ">0.2", "fzaninotto/faker": "^1.6", - "mustache/mustache": "~2.5" + "mustache/mustache": "~2.5", + "epfremme/swagger-php": "^2.0" }, "require-dev": { "squizlabs/php_codesniffer": "1.5.3", "sebastian/phpcpd": "~3.0", - "brainmaestro/composer-git-hooks": "^2.3" + "brainmaestro/composer-git-hooks": "^2.3", + "codeception/aspect-mock": "^2.0", + "codacy/coverage": "^1.4" }, "autoload": { "psr-4": { "Magento\\FunctionalTestingFramework\\": ["src/Magento/FunctionalTestingFramework"] } }, + "autoload-dev": { + "psr-4": { + "tests\\unit\\Magento\\FunctionalTestingFramework\\": ["dev/tests/unit/Magento/FunctionalTestingFramework"] + } + }, "extra": { "hooks": { "pre-push": "bin/copyright-check" diff --git a/dev/tests/_bootstrap.php b/dev/tests/_bootstrap.php index 57721a44e..f2da861f0 100644 --- a/dev/tests/_bootstrap.php +++ b/dev/tests/_bootstrap.php @@ -8,6 +8,13 @@ define('PROJECT_ROOT', dirname(dirname(__DIR__))); require_once PROJECT_ROOT . '/vendor/autoload.php'; +// Set up AspectMock +$kernel = \AspectMock\Kernel::getInstance(); +$kernel->init([ + 'debug' => true, + 'includePaths' => [PROJECT_ROOT . '/src'] +]); + // Load needed framework env params $TEST_ENVS = [ 'MAGENTO_BASE_URL' => 'http://baseurl:8080', @@ -23,7 +30,6 @@ // Add our test module to the whitelist putenv('MODULE_WHITELIST=Magento_TestModule'); - // Define our own set of paths for the tests defined('FW_BP') || define('FW_BP', PROJECT_ROOT); diff --git a/dev/tests/phpunit.xml b/dev/tests/phpunit.xml index 4751e1765..ea9f46865 100644 --- a/dev/tests/phpunit.xml +++ b/dev/tests/phpunit.xml @@ -9,7 +9,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd" convertNoticesToExceptions="false" - bootstrap="_bootstrap.php"> + bootstrap="_bootstrap.php" + backupGlobals="false"> verification @@ -27,4 +28,4 @@ ../../src/Magento/FunctionalTestingFramework/Util - \ No newline at end of file + diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Handlers/DataObjectHandlerTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Handlers/DataObjectHandlerTest.php new file mode 100644 index 000000000..c09e47478 --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Handlers/DataObjectHandlerTest.php @@ -0,0 +1,96 @@ + [ + 'EntityOne' => [ + 'type' => 'testType', + 'data' => [ + 0 => [ + 'key' => 'testKey', + 'value' => 'testValue' + ] + ] + ] + ] + ]; + + /** + * Set up everything required to mock DataObjectHander::getInstance() + * The first call to getInstance() uses these mocks to emulate the parser, initializing internal state + * according to the PARSER_OUTPUT value + */ + public static function setUpBeforeClass() + { + $mockDataProfileSchemaParser = AspectMock::double(DataProfileSchemaParser::class, [ + 'readDataProfiles' => self::PARSER_OUTPUT + ])->make(); + + $mockObjectManager = AspectMock::double(ObjectManager::class, [ + 'create' => $mockDataProfileSchemaParser + ])->make(); + + AspectMock::double(ObjectManagerFactory::class, [ + 'getObjectManager' => $mockObjectManager + ]); + } + + /** + * getAllObjects should contain the expected data object + */ + public function testGetAllObjects() + { + // Call the method under test + + $actual = DataObjectHandler::getInstance()->getAllObjects(); + + // Assert + + $expected = new EntityDataObject('EntityOne', 'testType', ['testkey' => 'testValue'], [], null, []); + $this->assertArrayHasKey('EntityOne', $actual); + $this->assertEquals($expected, $actual['EntityOne']); + } + + /** + * getObject should return the expected data object if it exists + */ + public function testGetObject() + { + // Call the method under test + + $actual = DataObjectHandler::getInstance()->getObject('EntityOne'); + + // Assert + + $expected = new EntityDataObject('EntityOne', 'testType', ['testkey' => 'testValue'], [], null, []); + $this->assertEquals($expected, $actual); + } + + /** + * getObject should return null if the data object does not exist + */ + public function testGetObjectNull() + { + $actual = DataObjectHandler::getInstance()->getObject('h953u789h0g73t521'); // doesnt exist + $this->assertNull($actual); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Handlers/OperationDefinitionObjectHandlerTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Handlers/OperationDefinitionObjectHandlerTest.php new file mode 100644 index 000000000..f08e659eb --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Handlers/OperationDefinitionObjectHandlerTest.php @@ -0,0 +1,20 @@ +markTestIncomplete('TODO'); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Objects/EntityDataObjectTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Objects/EntityDataObjectTest.php new file mode 100644 index 000000000..2dcff1eff --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Objects/EntityDataObjectTest.php @@ -0,0 +1,20 @@ +markTestIncomplete('TODO'); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Persist/OperationDataArrayResolverTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Persist/OperationDataArrayResolverTest.php new file mode 100644 index 000000000..513c80e9b --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/DataGenerator/Persist/OperationDataArrayResolverTest.php @@ -0,0 +1,347 @@ + [ + "name" => "Hopper", + "address" => ["city" => "Hawkins", "state" => "Indiana", "zip" => 78758], + "isPrimary" => true, + "gpa" => 3.5, + "phone" => 5555555 + ]]; + + const NESTED_METADATA_ARRAY_RESULT = ["parentType" => [ + "name" => "Hopper", + "isPrimary" => true, + "gpa" => 3.5, + "phone" => 5555555, + "address" => [ + ["city" => "Hawkins", "state" => "Indiana", "zip" => 78758], + ["city" => "Austin", "state" => "Texas", "zip" => 78701], + ] + ]]; + + /** + * Test a basic metadata resolve between primitive values and a primitive data set + * + * stringField + * intField + * boolField + * doubleField + * + */ + public function testBasicPrimitiveMetadataResolve() + { + // set up data object + $entityObjectBuilder = new EntityDataObjectBuilder(); + $testDataObject = $entityObjectBuilder->build(); + + // set up meta data operation elements + $operationElementBuilder = new OperationElementBuilder(); + $operationElement = $operationElementBuilder->build(); + + // resolve data object and metadata array + $operationDataArrayResolver = new OperationDataArrayResolver(); + $result = $operationDataArrayResolver->resolveOperationDataArray( + $testDataObject, + [$operationElement], + 'create' + ); + + // assert on result + $expectedResult = ["testType" => [ + "name" => "Hopper", + "gpa" => 3.5, + "phone" => 5555555, + "isPrimary" => true + ]]; + + $this->assertEquals($expectedResult, $result); + } + + /** + * Test a nested metadata operation resolve: + * + * someField + * objectRef + * + */ + public function testNestedMetadataResolve() + { + // set up data objects + $entityDataObjBuilder = new EntityDataObjectBuilder(); + $parentDataObject = $entityDataObjBuilder + ->withName("parentObject") + ->withType("parentType") + ->withLinkedEntities(['childObject' => 'childType']) + ->build(); + + $childDataObject = $entityDataObjBuilder + ->withName("childObject") + ->withType("childType") + ->withDataFields(["city" => "Hawkins", "state" => "Indiana", "zip" => "78758"]) + ->build(); + + // mock data object handler + $mockDOHInstance = AspectMock::double(DataObjectHandler::class, ['getObject' => $childDataObject])->make(); + AspectMock::double(DataObjectHandler::class, ['getInstance' => $mockDOHInstance]); + + // set up metadata objects + $parentOpElementBuilder = new OperationElementBuilder(); + $parentElement = $parentOpElementBuilder + ->withKey("parentType") + ->withType("parentType") + ->addFields(["address" => "childType"]) + ->build(); + + $operationDefinitionBuilder = new OperationDefinitionBuilder(); + $childOperationDefinition = $operationDefinitionBuilder + ->withName("createChildType") + ->withOperation("create") + ->withType("childType") + ->withMetadata([ + "city" => "string", + "state" => "string", + "zip" => "integer" + ])->build(); + + // mock meta data object handler + $mockDOHInstance = AspectMock::double( + OperationDefinitionObjectHandler::class, + ['getObject' => $childOperationDefinition] + )->make(); + AspectMock::double(OperationDefinitionObjectHandler::class, ['getInstance' => $mockDOHInstance]); + + // resolve data object and metadata array + $operationResolver = new OperationDataArrayResolver(); + $result = $operationResolver->resolveOperationDataArray($parentDataObject, [$parentElement], "create", false); + + // assert on the result + $this->assertEquals(self::NESTED_METADATA_EXPECTED_RESULT, $result); + } + + /** + * Test a nested metadata operation: + * + * someField + * + * anotherField + * + * + */ + public function testNestedMetadata() + { + // set up data objects + $entityDataObjectBuilder = new EntityDataObjectBuilder(); + $parentDataObject = $entityDataObjectBuilder + ->withName("parentObject") + ->withType("parentType") + ->withLinkedEntities(['childObject' => 'childType']) + ->build(); + + $childDataObject = $entityDataObjectBuilder + ->withName("childObject") + ->withType("childType") + ->withDataFields(["city" => "Hawkins", "state" => "Indiana", "zip" => "78758"]) + ->build(); + + // mock data object handler + $mockDOHInstance = AspectMock::double(DataObjectHandler::class, ['getObject' => $childDataObject])->make(); + AspectMock::double(DataObjectHandler::class, ['getInstance' => $mockDOHInstance]); + + // set up metadata objects + $childOpElementBuilder = new OperationElementBuilder(); + $childElement = $childOpElementBuilder + ->withKey("address") + ->withType("childType") + ->withFields(["city" => "string", "state" => "string", "zip" => "integer"]) + ->build(); + + $parentOpElementBuilder = new OperationElementBuilder(); + $parentElement = $parentOpElementBuilder + ->withKey("parentType") + ->withType("parentType") + ->addElements(["address" => $childElement]) + ->build(); + + // resolve data object and metadata array + $operationResolver = new OperationDataArrayResolver(); + $result = $operationResolver->resolveOperationDataArray($parentDataObject, [$parentElement], "create", false); + + // assert on the result + $this->assertEquals(self::NESTED_METADATA_EXPECTED_RESULT, $result); + } + + /** + * Test a nested metadata operation with a declared object: + * + * someField + * + * + * anotherField + * + * + */ + public function testNestedMetadataArrayOfObjects() + { + // set up data objects + $entityDataObjectBuilder = new EntityDataObjectBuilder(); + $parentDataObject = $entityDataObjectBuilder + ->withName("parentObject") + ->withType("parentType") + ->withLinkedEntities(['childObject1' => 'childType', 'childObject2' => 'childType']) + ->build(); + + // mock data object handler + $mockDOHInstance = AspectMock::double(DataObjectHandler::class, ["getObject" => function ($name) { + $entityDataObjectBuilder = new EntityDataObjectBuilder(); + + if ($name == "childObject1") { + return $entityDataObjectBuilder + ->withName("childObject1") + ->withType("childType") + ->withDataFields(["city" => "Hawkins", "state" => "Indiana", "zip" => "78758"]) + ->build(); + } + + if ($name == "childObject2") { + return $entityDataObjectBuilder + ->withName("childObject2") + ->withType("childType") + ->withDataFields(["city" => "Austin", "state" => "Texas", "zip" => "78701"]) + ->build(); + } + }])->make(); + AspectMock::double(DataObjectHandler::class, ['getInstance' => $mockDOHInstance]); + + // set up metadata objects + $childOpElementBuilder = new OperationElementBuilder(); + $childElement = $childOpElementBuilder + ->withKey("childType") + ->withType("childType") + ->withFields(["city" => "string", "state" => "string", "zip" => "integer"]) + ->build(); + + $arrayOpElementBuilder = new OperationElementBuilder(); + $arrayElement = $arrayOpElementBuilder + ->withKey("address") + ->withType("childType") + ->withFields([]) + ->withElementType(OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY) + ->withNestedElements(["childType" => $childElement]) + ->build(); + + $parentOpElementBuilder = new OperationElementBuilder(); + $parentElement = $parentOpElementBuilder + ->withKey("parentType") + ->withType("parentType") + ->addElements(["address" => $arrayElement]) + ->build(); + + // resolve data object and metadata array + $operationResolver = new OperationDataArrayResolver(); + $result = $operationResolver->resolveOperationDataArray($parentDataObject, [$parentElement], "create", false); + + // Do assert on result here + $this->assertEquals(self::NESTED_METADATA_ARRAY_RESULT, $result); + } + + /** + * Test a nested metadata operation with a value pointing to an object ref: + * + * someField + * + * object + * + */ + public function testNestedMetadataArrayOfValue() + { + // set up data objects + $entityDataObjectBuilder = new EntityDataObjectBuilder(); + $parentDataObject = $entityDataObjectBuilder + ->withName("parentObject") + ->withType("parentType") + ->withLinkedEntities(['childObject1' => 'childType', 'childObject2' => 'childType']) + ->build(); + + // mock data object handler + $mockDOHInstance = AspectMock::double(DataObjectHandler::class, ["getObject" => function ($name) { + $entityDataObjectBuilder = new EntityDataObjectBuilder(); + + if ($name == "childObject1") { + return $entityDataObjectBuilder + ->withName("childObject1") + ->withType("childType") + ->withDataFields(["city" => "Hawkins", "state" => "Indiana", "zip" => "78758"]) + ->build(); + }; + + if ($name == "childObject2") { + return $entityDataObjectBuilder + ->withName("childObject2") + ->withType("childType") + ->withDataFields(["city" => "Austin", "state" => "Texas", "zip" => "78701"]) + ->build(); + } + }])->make(); + AspectMock::double(DataObjectHandler::class, ['getInstance' => $mockDOHInstance]); + + // set up metadata objects + $arrayOpElementBuilder = new OperationElementBuilder(); + $arrayElement = $arrayOpElementBuilder + ->withKey("address") + ->withType("childType") + ->withElementType(OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY) + ->withNestedElements([]) + ->withFields([]) + ->build(); + + $parentOpElementBuilder = new OperationElementBuilder(); + $parentElement = $parentOpElementBuilder + ->withKey("parentType") + ->withType("parentType") + ->addElements(["address" => $arrayElement]) + ->build(); + + $operationDefinitionBuilder = new OperationDefinitionBuilder(); + $childOperationDefinition = $operationDefinitionBuilder + ->withName("createChildType") + ->withOperation("create") + ->withType("childType") + ->withMetadata([ + "city" => "string", + "state" => "string", + "zip" => "integer" + ])->build(); + + // mock meta data object handler + $mockDOHInstance = AspectMock::double( + OperationDefinitionObjectHandler::class, + ['getObject' => $childOperationDefinition] + )->make(); + AspectMock::double(OperationDefinitionObjectHandler::class, ['getInstance' => $mockDOHInstance]); + + // resolve data object and metadata array + $operationResolver = new OperationDataArrayResolver(); + $result = $operationResolver->resolveOperationDataArray($parentDataObject, [$parentElement], "create", false); + + // Do assert on result here + $this->assertEquals(self::NESTED_METADATA_ARRAY_RESULT, $result); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/PageObjectHandlerTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/PageObjectHandlerTest.php new file mode 100644 index 000000000..57c4cbe21 --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/PageObjectHandlerTest.php @@ -0,0 +1,17 @@ +markTestIncomplete('TODO'); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/SectionObjectHandlerTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/SectionObjectHandlerTest.php new file mode 100644 index 000000000..95cbb12db --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/SectionObjectHandlerTest.php @@ -0,0 +1,17 @@ +markTestIncomplete('TODO'); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/ElementObjectTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/ElementObjectTest.php new file mode 100644 index 000000000..00d5e9479 --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/ElementObjectTest.php @@ -0,0 +1,66 @@ +assertNull($element->getTimeout()); + } + + /** + * Timeout should be cast to an integer + */ + public function testTimeoutNotNull() + { + $element = new ElementObject('name', 'type', 'selector', null, '15', false); + $timeout = $element->getTimeout(); + $this->assertEquals(15, $timeout); + $this->assertInternalType('int', $timeout); + } + + /** + * Timeout should be 0 when a string is the value + */ + public function testTimeoutCastFromString() + { + $element = new ElementObject('name', 'type', 'selector', null, 'helloString', true); + $timeout = $element->getTimeout(); + $this->assertEquals(0, $timeout); + $this->assertInternalType('int', $timeout); + } + + /** + * An exception should be thrown if both a selector and locatorFunction are passed + */ + public function testBothSelectorAndLocatorFunction() + { + $this->expectException(XmlException::class); + new ElementObject('name', 'type', 'selector', 'cantHaveThisAndSelector', '-', false); + } + + /** + * An exception should be thrown if neither a selector nor locatorFunction are passed + */ + public function testNeitherSelectorNorLocatorFunction() + { + $this->expectException(XmlException::class); + new ElementObject('name', 'type', null, null, '-', false); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/PageObjectTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/PageObjectTest.php new file mode 100644 index 000000000..e83154b19 --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/PageObjectTest.php @@ -0,0 +1,34 @@ +assertTrue($page->hasSection('section1')); + } + + /** + * Assert that the page object doesn't have a section + */ + public function testDoesntHaveSection() + { + $page = new PageObject('name', 'urlPath', 'module', ['section1', 'section2'], false); + $this->assertFalse($page->hasSection('section3')); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/SectionObjectTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/SectionObjectTest.php new file mode 100644 index 000000000..6257ee0db --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Page/Objects/SectionObjectTest.php @@ -0,0 +1,75 @@ + $element1, + 'element2' => $element2 + ]; + $section = new SectionObject('test', $elements); + $this->assertTrue($section->hasElement('element1')); + } + + /** + * Assert that the section object doesn't have an element + */ + public function testDoesntHaveElement() + { + $element2 = new ElementObject('element2', 'type', '#selector', null, '42', true); + $elements = [ + 'element2' => $element2 + ]; + $section = new SectionObject('test', $elements); + $this->assertFalse($section->hasElement('element1')); + } + + /** + * Assert that an element object is returned + */ + public function testGetElement() + { + $element1 = new ElementObject('element1', 'type', '#selector', null, '41', false); + $element2 = new ElementObject('element2', 'type', '#selector', null, '42', true); + $elements = [ + 'element1' => $element1, + 'element2' => $element2 + ]; + $section = new SectionObject('test', $elements); + $gotElement = $section->getElement('element2'); + $this->assertInstanceOf(ElementObject::class, $gotElement); + $this->assertEquals($gotElement, $element2); + } + + /** + * Assert that null is returned if no such element + */ + public function testNullGetElement() + { + $element1 = new ElementObject('element1', 'type', '#selector', null, '41', false); + $elements = [ + 'element1' => $element1 + ]; + $section = new SectionObject('test', $elements); + $this->assertNull($section->getElement('element2')); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Test/Objects/ActionObjectTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Objects/ActionObjectTest.php new file mode 100644 index 000000000..5ab71810c --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Objects/ActionObjectTest.php @@ -0,0 +1,191 @@ +assertEquals(0, $actionObject->getOrderOffset()); + } + + /** + * The order offset should be 1 when the action is instantiated with 'after' + */ + public function testConstructOrderAfter() + { + $actionObject = new ActionObject('mergeKey', 'type', [], null, 'after'); + $this->assertEquals(1, $actionObject->getOrderOffset()); + } + + /** + * {{Section.element}} should be replaced with #theElementSelector + */ + public function testResolveElementInSelector() + { + // Set up mocks + $actionObject = new ActionObject('merge123', 'fillField', [ + 'selector' => '{{SectionObject.elementObject}}', + 'userInput' => 'Hello world' + ]); + $elementObject = new ElementObject('elementObject', 'button', '#replacementSelector', null, '42', false); + $sectionObject = new SectionObject('SectionObject', ['elementObject' => $elementObject]); + $instance = AspectMock::double(SectionObjectHandler::class, ['getObject' => $sectionObject]) + ->make(); // bypass the private constructor + AspectMock::double(SectionObjectHandler::class, ['getInstance' => $instance]); + + // Call the method under test + $actionObject->resolveReferences(); + + // Verify + $expected = [ + 'selector' => '#replacementSelector', + 'userInput' => 'Hello world' + ]; + $this->assertEquals($expected, $actionObject->getCustomActionAttributes()); + } + + /** + * {{Section.element(param)}} should be replaced + */ + public function testResolveSelectorWithOneParam() + { + $this->markTestIncomplete('TODO'); + } + + /** + * {{Section.element(param1,param2)}} should be replaced + */ + public function testResolveSelectorWithManyParams() + { + $this->markTestIncomplete('TODO'); + } + + /** + * Timeout property on the ActionObject should be set if the ElementObject has a timeout + */ + public function testTimeoutFromElement() + { + // Set up mocks + $actionObject = new ActionObject('merge123', 'click', [ + 'selector' => '{{SectionObject.elementObject}}' + ]); + $elementObject = new ElementObject('elementObject', 'button', '#replacementSelector', null, '42', false); + $sectionObject = new SectionObject('SectionObject', ['elementObject' => $elementObject]); + $instance = AspectMock::double(SectionObjectHandler::class, ['getObject' => $sectionObject]) + ->make(); // bypass the private constructor + AspectMock::double(SectionObjectHandler::class, ['getInstance' => $instance]); + + // Call the method under test + $actionObject->resolveReferences(); + + // Verify + $this->assertEquals(42, $actionObject->getTimeout()); + } + + /** + * {{PageObject.url}} should be replaced with someUrl.html + */ + public function testResolveUrl() + { + // Set up mocks + $actionObject = new ActionObject('merge123', 'amOnPage', [ + 'url' => '{{PageObject.url}}' + ]); + $pageObject = new PageObject('PageObject', '/replacement/url.html', 'Test', [], false); + $instance = AspectMock::double(PageObjectHandler::class, ['getObject' => $pageObject]) + ->make(); // bypass the private constructor + AspectMock::double(PageObjectHandler::class, ['getInstance' => $instance]); + + // Call the method under test + $actionObject->resolveReferences(); + + // Verify + $expected = [ + 'url' => '/replacement/url.html' + ]; + $this->assertEquals($expected, $actionObject->getCustomActionAttributes()); + } + + /** + * {{PageObject.url(param)}} should be replaced + */ + public function testResolveUrlWithOneParam() + { + $this->markTestIncomplete('TODO'); + } + + /** + * {{PageObject.url(param1,param2,param3)}} should be replaced + */ + public function testResolveUrlWithManyParams() + { + $this->markTestIncomplete('TODO'); + } + + /** + * {{EntityDataObject.key}} should be replaced with someDataValue + */ + public function testResolveDataInUserInput() + { + // Set up mocks + $actionObject = new ActionObject('merge123', 'fillField', [ + 'selector' => '#selector', + 'userInput' => '{{EntityDataObject.key}}' + ]); + $entityDataObject = new EntityDataObject('EntityDataObject', 'test', [ + 'key' => 'replacementData' + ], [], '', ''); + $instance = AspectMock::double(DataObjectHandler::class, ['getObject' => $entityDataObject]) + ->make(); // bypass the private constructor + AspectMock::double(DataObjectHandler::class, ['getInstance' => $instance]); + + // Call the method under test + $actionObject->resolveReferences(); + + // Verify + $expected = [ + 'selector' => '#selector', + 'userInput' => 'replacementData' + ]; + $this->assertEquals($expected, $actionObject->getCustomActionAttributes()); + } + + /** + * $testScopeData$ (single dollar sign) should be replaced + */ + public function testTestScopeDataResolution() + { + $this->markTestIncomplete('TODO'); + } + + /** + * $$cestScopeData$$ (double dollar sign) should be replaced + */ + public function testCestScopeDataResolution() + { + $this->markTestIncomplete('TODO'); + } +} diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionMergeUtilTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionMergeUtilTest.php index 495f6eff1..bbe88bf54 100644 --- a/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionMergeUtilTest.php +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionMergeUtilTest.php @@ -5,10 +5,10 @@ */ namespace tests\unit\Magento\FunctionalTestFramework\Test\Util; +use AspectMock\Test as AspectMock; use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; use Magento\FunctionalTestingFramework\Test\Objects\ActionObject; -use Magento\FunctionalTestingFramework\Test\Objects\TestObject; use Magento\FunctionalTestingFramework\Test\Util\ActionMergeUtil; use Magento\FunctionalTestingFramework\Test\Util\ActionObjectExtractor; use PHPUnit\Framework\TestCase; @@ -101,7 +101,7 @@ public function testResolveActionStepOrdering() */ public function testResolveActionStepSectionData() { - //TODO implement section object mocker and test + $this->markTestIncomplete('TODO'); } /** @@ -109,9 +109,9 @@ public function testResolveActionStepSectionData() * * @return void */ - public function resolveActionStepPageData() + public function testResolveActionStepPageData() { - //TODO implement page object mocker and test + $this->markTestIncomplete('TODO'); } /** @@ -130,18 +130,13 @@ public function testResolveActionStepEntityData() $actionName = "myAction"; $actionType = "myCustomType"; - // Set up mock data object $mockData = [$dataFieldName => $dataFieldValue]; $mockDataObject = new EntityDataObject($dataObjectName, $dataObjectType, $mockData, null, null, null); // Set up mock DataObject Handler - $mockDataHandler = $this->createMock(DataObjectHandler::class); - $mockDataHandler->expects($this->any()) - ->method('getObject') - ->with($this->matches($dataObjectName)) - ->willReturn($mockDataObject); - DataObjectHandlerReflectionUtil::setupMock($mockDataHandler); + $mockDOHInstance = AspectMock::double(DataObjectHandler::class, ['getObject' => $mockDataObject])->make(); + AspectMock::double(DataObjectHandler::class, ['getInstance' => $mockDOHInstance]); // Create test object and action object $actionAttributes = [$userInputKey => $userinputValue]; @@ -153,7 +148,5 @@ public function testResolveActionStepEntityData() $resolvedActions = $mergeUtil->resolveActionSteps($actions); $this->assertEquals($dataFieldValue, $resolvedActions[$actionName]->getCustomActionAttributes()[$userInputKey]); - - DataObjectHandlerReflectionUtil::tearDown(); } } diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/TestNameValidationUtilTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/TestNameValidationUtilTest.php new file mode 100644 index 000000000..8b50062ed --- /dev/null +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/TestNameValidationUtilTest.php @@ -0,0 +1,74 @@ +validateBlacklistedTestName("{{curlyBraces}}"); + } + + /** + * Validate name with quotation marks throws exception + */ + public function testQuotesInTestName() + { + $this->validateBlacklistedTestName("\"quotes\""); + } + + /** + * Validate name with single quotes throws exception + */ + public function testSingleQuotesInTestName() + { + $this->validateBlacklistedTestName("'singleQuotes'"); + } + + /** + * Validate name with parenthesis throws execption + */ + public function testParenthesesInTestName() + { + $this->validateBlacklistedTestName("(parenthesis)"); + } + + /** + * Validate name with dollar signs throws exception + */ + public function testDollarSignInTestName() + { + $this->validateBlacklistedTestName("\$dollarSign\$"); + } + + /** + * Validate name with spaces throws exception + */ + public function testSpacesInTestName() + { + $this->validateBlacklistedTestName("Test Name With Spaces"); + } + + /** + * Method which takes the name of the test expecting an invalid char. Runs the validation method against name. + * + * @param string $testName + * @return void + */ + private function validateBlacklistedTestName($testName) + { + $this->expectException(XmlException::class); + TestNameValidationUtil::validateName($testName); + } +} diff --git a/dev/tests/unit/Util/DataObjectHandlerReflectionUtil.php b/dev/tests/unit/Util/DataObjectHandlerReflectionUtil.php deleted file mode 100644 index 557ab5772..000000000 --- a/dev/tests/unit/Util/DataObjectHandlerReflectionUtil.php +++ /dev/null @@ -1,47 +0,0 @@ -bindTo(null, DataObjectHandler::class); - $setMockStatic($mockObject); - } - - /** - * Sets the Data Object Handler Instance to a null value for re-initialization. - */ - public static function tearDown() - { - $resetStatic = function () { - static::$DATA_OBJECT_HANDLER = null; - }; - - $resetMockStatic = $resetStatic->bindTo(null, DataObjectHandler::class); - $resetMockStatic(); - } -} \ No newline at end of file diff --git a/dev/tests/unit/Util/EntityDataObjectBuilder.php b/dev/tests/unit/Util/EntityDataObjectBuilder.php new file mode 100644 index 000000000..ead183b8c --- /dev/null +++ b/dev/tests/unit/Util/EntityDataObjectBuilder.php @@ -0,0 +1,116 @@ + "Hopper", + "gpa" => "3.5", + "phone" => "5555555", + "isprimary" => "true" + ]; + + /** + * Name of the data object. + * + * @var string + */ + private $name = "testDataObject"; + + /** + * Name of the data object type (e.g. customer, category etc.) + * + * @var string + */ + private $type = "testType"; + + /** + * A flat array containing linked entity name => linked entity type. + * + * @var array + */ + private $linkedEntities = []; + + /** + * An array contain references to data to be resolved by the api. + * + * @var array + */ + private $vars = []; + + /** + * A function which will build an Entity Data Object with the params specified by the object. + * + * @return EntityDataObject + */ + public function build() + { + return new EntityDataObject( + $this->name, + $this->type, + $this->data, + $this->linkedEntities, + null, + $this->vars + ); + } + + /** + * Sets the name of the EntityDataObject. + * + * @param string $name + * @return EntityDataObjectBuilder + */ + public function withName($name) + { + $this->name = $name; + return $this; + } + + /** + * Sets the type of the EntityDataObject. + * + * @param string $type + * @return EntityDataObjectBuilder + */ + public function withType($type) + { + $this->type = $type; + return $this; + } + + /** + * Sets the data fields on the object to the data field array specified in the argument. + * + * @param array $fields + * @return EntityDataObjectBuilder + */ + public function withDataFields($fields) + { + $this->data = $fields; + return $this; + } + + /** + * Sets the linked entities specified by the user as a param for Entity Data Object creation. + * + * @param array $linkedEntities + * @return EntityDataObjectBuilder + */ + public function withLinkedEntities($linkedEntities) + { + $this->linkedEntities = $linkedEntities; + return $this; + } +} diff --git a/dev/tests/unit/Util/ObjectHandlerReflectionUtilInterface.php b/dev/tests/unit/Util/ObjectHandlerReflectionUtilInterface.php deleted file mode 100644 index 145c1a0e3..000000000 --- a/dev/tests/unit/Util/ObjectHandlerReflectionUtilInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -name, + $this->operation, + $this->type, + null, + null, + null, + null, + null, + $this->metadata, + null + ); + } + + /** + * Sets the name of the operation definition to be built. + * + * @param string $name + * @return OperationDefinitionBuilder + */ + public function withName($name) + { + $this->name = $name; + return $this; + } + + /** + * Sets the name of the operation for the object to be built. + * + * @param string $operation + * @return OperationDefinitionBuilder + */ + public function withOperation($operation) + { + $this->operation = $operation; + return $this; + } + + /** + * Sets the name of the type of operation (e.g. create, delete) + * + * @param string $type + * @return OperationDefinitionBuilder + */ + public function withType($type) + { + $this->type = $type; + return $this; + } + + /** + * Takes an array of values => type or an array of operation elements and transforms into operation metadata. + * + * @param array $metadata + * @return OperationDefinitionBuilder + */ + public function withMetadata($metadata) + { + $primitives = []; + foreach ($metadata as $fieldName => $value) { + // type check here TODO + if (is_string($value)) { + $primitives[$fieldName] = $value; + } else { + $this->metadata[] = $value; + } + } + + $this->metadata = array_merge( + $this->metadata, + OperationElementBuilder::buildOperationElementFields($primitives) + ); + return $this; + } +} diff --git a/dev/tests/unit/Util/OperationElementBuilder.php b/dev/tests/unit/Util/OperationElementBuilder.php new file mode 100644 index 000000000..a7a021ac2 --- /dev/null +++ b/dev/tests/unit/Util/OperationElementBuilder.php @@ -0,0 +1,191 @@ + valueType). By default this + * value contains a set of primitive fields. + * + * @var array + */ + private $fields = [ + 'name' => 'string', + 'gpa' => 'double', + 'phone' => 'integer', + 'isPrimary' => 'boolean' + ]; + + private $nestedMetadata = []; + + /** + * The key to which the metadata defined will be mapped + * in JSON { key : value } + * + * @var string + */ + private $key = 'testType'; + + /** + * The type of value to which the metadata defined will be mapped (e.g. string, boolean, user defined object). + * in JSON { key : value } + * + * @var string + */ + private $type = 'testType'; + + /** + * The element type to which the metadata defined will be transformed into. + * in JSON: + * { } <- object + * [ ] <- array + * key : value <- field + * + * @var string + */ + private $elementType = OperationDefinitionObjectHandler::ENTITY_OPERATION_OBJECT; + + /** + * The array of elements which the Operation Element contains to resolve declarations within arrays specifically. + * Arrays can take object references or definitions within themselves. This metadata has to be at a parent level in + * order to resolve properly. + * + * @var array + */ + private $nestedElements; + + /** + * Build function which takes params defined by the user and returns a new Operation Element. + * + * @return OperationElement + */ + public function build() + { + return new OperationElement( + $this->key, + $this->type, + $this->elementType, + null, + $this->nestedElements, + array_merge($this->nestedMetadata, self::buildOperationElementFields($this->fields)) + ); + } + + /** + * Sets a new element type, overwrites any existing. + * + * @param string $elementType + * @return OperationElementBuilder + */ + public function withElementType($elementType) + { + $this->elementType = $elementType; + return $this; + } + + /** + * Set a new set of fields or operation elements + * + * @param array $fields + * @return OperationElementBuilder + */ + public function withFields($fields) + { + $this->fields = $fields; + return $this; + } + + /** + * Sets a key for the operation element. See ref to param key for explanation. + * + * @param string $key + * @return OperationElementBuilder + */ + public function withKey($key) + { + $this->key = $key; + return $this; + } + + /** + * Sets a type for the operation element. See ref to param type for explanation. + * + * @param string $type + * @return OperationElementBuilder + */ + public function withType($type) + { + $this->type = $type; + return $this; + } + + /** + * Adds a set of new Operation Elements to the nested metadata. + * + * @param array $elementsToAdd + * @return OperationElementBuilder + */ + public function addElements($elementsToAdd) + { + foreach ($elementsToAdd as $fieldKey => $metadata) { + $this->nestedMetadata[$fieldKey] = $metadata; + } + + return $this; + } + + /** + * Adds a new set of fields (value => type) into an object parameter to be converted to Operation Elements. + * + * @param $fieldsToAdd + * @return OperationElementBuilder + */ + public function addFields($fieldsToAdd) + { + foreach ($fieldsToAdd as $fieldKey => $type) { + $this->fields[$fieldKey] = $type; + } + + return $this; + } + + /** + * Sets an array nested elements to an object property. + * + * @param array $nestedElements + * @return OperationElementBuilder + */ + public function withNestedElements($nestedElements) + { + $this->nestedElements = $nestedElements; + return $this; + } + + /** + * Takes an array of fields (value => type) and returns an array of Operations Elements of type field. + * + * @param array $fields + * @return array + */ + public static function buildOperationElementFields($fields) + { + $operationElements = []; + foreach ($fields as $fieldName => $type) { + $operationElements[] = new OperationElement( + $fieldName, + $type, + null, + OperationDefinitionObjectHandler::ENTITY_OPERATION_ENTRY + ); + } + + return $operationElements; + } +} diff --git a/dev/tests/verification/Resources/ActionGroupFunctionalCest.txt b/dev/tests/verification/Resources/ActionGroupFunctionalCest.txt index a2b40ac98..39a406e20 100644 --- a/dev/tests/verification/Resources/ActionGroupFunctionalCest.txt +++ b/dev/tests/verification/Resources/ActionGroupFunctionalCest.txt @@ -5,6 +5,7 @@ use Magento\FunctionalTestingFramework\AcceptanceTester; use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; +use \Codeception\Util\Locator; use Yandex\Allure\Adapter\Annotation\Features; use Yandex\Allure\Adapter\Annotation\Stories; use Yandex\Allure\Adapter\Annotation\Title; @@ -16,7 +17,7 @@ use Yandex\Allure\Adapter\Annotation\TestCaseId; /** * @Severity(level = SeverityLevel::CRITICAL) - * @Title("Title") + * @Title("A Functional Cest") * @group functional * @Features({"Action Group Functional Cest"}) * @Stories({"MQE-433"}) @@ -109,7 +110,7 @@ class ActionGroupFunctionalCest $I->amOnPage("/" . $createPerson->getCreatedDataByName('firstname') . "/" . $createPerson->getCreatedDataByName('lastname') . ".html"); $I->fillField("#foo", $createPerson->getCreatedDataByName('firstname')); $I->fillField("#bar", $createPerson->getCreatedDataByName('lastname')); - $I->searchAndMultiSelectOption("#foo", [$createPerson->getCreatedDataByName('firstname') . "", "" . $createPerson->getCreatedDataByName('lastname')]); + $I->searchAndMultiSelectOption("#foo", [$createPerson->getCreatedDataByName('firstname'), $createPerson->getCreatedDataByName('lastname')]); $I->see("#element ." . $createPerson->getCreatedDataByName('firstname')); } @@ -123,7 +124,7 @@ class ActionGroupFunctionalCest $I->amOnPage("/" . $this->createPersonParam->getCreatedDataByName('firstname') . "/" . $this->createPersonParam->getCreatedDataByName('lastname') . ".html"); $I->fillField("#foo", $this->createPersonParam->getCreatedDataByName('firstname')); $I->fillField("#bar", $this->createPersonParam->getCreatedDataByName('lastname')); - $I->searchAndMultiSelectOption("#foo", [$this->createPersonParam->getCreatedDataByName('firstname') . "", "" . $this->createPersonParam->getCreatedDataByName('lastname')]); + $I->searchAndMultiSelectOption("#foo", [$this->createPersonParam->getCreatedDataByName('firstname'), $this->createPersonParam->getCreatedDataByName('lastname')]); $I->see("#element ." . $this->createPersonParam->getCreatedDataByName('firstname')); } diff --git a/dev/tests/verification/Resources/AssertCest.txt b/dev/tests/verification/Resources/AssertCest.txt new file mode 100644 index 000000000..fd2fe2259 --- /dev/null +++ b/dev/tests/verification/Resources/AssertCest.txt @@ -0,0 +1,102 @@ +amGoingTo("create entity that has the mergeKey: createData1"); + $ReplacementPerson = DataObjectHandler::getInstance()->getObject("ReplacementPerson"); + $this->createData1 = new DataPersistenceHandler($ReplacementPerson); + $this->createData1->createEntity(); + } + + /** + * @Parameter(name = "AcceptanceTester", value="$I") + * @param AcceptanceTester $I + * @return void + */ + public function AssertTest(AcceptanceTester $I) + { + $I->amGoingTo("create entity that has the mergeKey: createData2"); + $UniquePerson = DataObjectHandler::getInstance()->getObject("UniquePerson"); + $createData2 = new DataPersistenceHandler($UniquePerson); + $createData2->createEntity(); + $text = $I->grabTextFrom(".copyright>span"); + $I->comment("asserts without variable replacement"); + $I->assertArrayHasKey("apple", ['orange' => 2, 'apple' => 1], "pass"); + $I->assertArrayNotHasKey("kiwi", ['orange' => 2, 'apple' => 1], "pass"); + $I->assertArraySubset([1, 2], [1, 2, 3, 5], "pass"); + $I->assertContains("ab", ['item1' => 'a', 'item2' => 'ab'], "pass"); + $I->assertCount(2, ['a', 'b'], "pass"); + $I->assertEmpty([], "pass"); + $I->assertEquals($text, "Copyright © 2013-2017 Magento, Inc. All rights reserved.", "pass"); + $I->assertEquals("Copyright © 2013-2017 Magento, Inc. All rights reserved.", $text, "pass"); + $I->assertFalse(false, "pass"); + $I->assertFileNotExists("/out.txt", "pass"); + $I->assertFileNotExists($text, "pass"); + $I->assertGreaterOrEquals(2, 5, "pass"); + $I->assertGreaterThan(2, 5, "pass"); + $I->assertGreaterThanOrEqual(2, 5, "pass"); + $I->assertInternalType("string", "xyz", "pass"); + $I->assertInternalType("int", 21, "pass"); + $I->assertInternalType("string", $text, "pass"); + $I->assertLessOrEquals(5, 2, "pass"); + $I->assertLessThan(5, 2, "pass"); + $I->assertLessThanOrEqual(5, 2, "pass"); + $I->assertNotContains("bc", ['item1' => 'a', 'item2' => 'ab'], "pass"); + $I->assertNotContains("bc", $text, "pass"); + $I->assertNotEmpty([1, 2], "pass"); + $I->assertNotEmpty($text, "pass"); + $I->assertNotEquals(2, 5, "pass", 0); + $I->assertNotNull("abc", "pass"); + $I->assertNotNull($text, "pass"); + $I->assertNotRegExp("/foo/", "bar", "pass"); + $I->assertNotSame("log", "tag", "pass"); + $I->assertRegExp("/foo/", "foo", "pass"); + $I->assertSame("bar", "bar", "pass"); + $I->assertStringStartsNotWith("a", "banana", "pass"); + $I->assertStringStartsWith("a", "apple", "pass"); + $I->assertTrue(true, "pass"); + $I->comment("string type that use created data"); + $I->assertStringStartsWith("D", $this->createData1->getCreatedDataByName('lastname') . ", " . $this->createData1->getCreatedDataByName('firstname'), "fail"); + $I->assertStringStartsNotWith("W", $createData2->getCreatedDataByName('firstname') . " " . $createData2->getCreatedDataByName('lastname'), "pass"); + $I->assertEquals($this->createData1->getCreatedDataByName('lastname'), $this->createData1->getCreatedDataByName('lastname'), "pass"); + $I->comment("array type that use created data"); + $I->assertArraySubset([$this->createData1->getCreatedDataByName('lastname'), $this->createData1->getCreatedDataByName('firstname')], [$this->createData1->getCreatedDataByName('lastname'), $this->createData1->getCreatedDataByName('firstname'), "1"], "pass"); + $I->assertArraySubset([$createData2->getCreatedDataByName('firstname'), $createData2->getCreatedDataByName('lastname')], [$createData2->getCreatedDataByName('firstname'), $createData2->getCreatedDataByName('lastname'), "1"], "pass"); + $I->assertArrayHasKey("lastname", ['lastname' => $this->createData1->getCreatedDataByName('lastname'), 'firstname' => $this->createData1->getCreatedDataByName('firstname')], "pass"); + $I->assertArrayHasKey("lastname", ['lastname' => $createData2->getCreatedDataByName('lastname'), 'firstname' => $createData2->getCreatedDataByName('firstname')], "pass"); + $I->assertInstanceOf(User::class, $text, "pass"); + $I->assertNotInstanceOf(User::class, 21, "pass"); + $I->assertFileExists($text, "pass"); + $I->assertFileExists("AssertCest.php", "pass"); + $I->assertIsEmpty($text, "pass"); + $I->assertNull($text, "pass"); + $I->expectException(new MyException('exception msg'), function() {$this->doSomethingBad();}); + $I->fail("fail"); + $I->fail($createData2->getCreatedDataByName('firstname') . " " . $createData2->getCreatedDataByName('lastname')); + $I->fail($this->createData1->getCreatedDataByName('firstname') . " " . $this->createData1->getCreatedDataByName('lastname')); + } +} diff --git a/dev/tests/verification/Resources/BasicFunctionalCest.txt b/dev/tests/verification/Resources/BasicFunctionalCest.txt index 94bba2310..b7afc27d9 100644 --- a/dev/tests/verification/Resources/BasicFunctionalCest.txt +++ b/dev/tests/verification/Resources/BasicFunctionalCest.txt @@ -5,6 +5,7 @@ use Magento\FunctionalTestingFramework\AcceptanceTester; use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; +use \Codeception\Util\Locator; use Yandex\Allure\Adapter\Annotation\Features; use Yandex\Allure\Adapter\Annotation\Stories; use Yandex\Allure\Adapter\Annotation\Title; @@ -16,7 +17,7 @@ use Yandex\Allure\Adapter\Annotation\TestCaseId; /** * @Severity(level = SeverityLevel::CRITICAL) - * @Title("Title") + * @Title("A Functional Cest") * @group functional * @Features({"Basic Functional Cest"}) * @Stories({"MQE-305"}) @@ -36,10 +37,10 @@ class BasicFunctionalCest /** * @Severity(level = SeverityLevel::SEVERE) * @Title("Basic Functional Test") + * @group functionalTest * @Features({"Hardcoded Functional Test"}) * @Stories({"MQE-425"}) * @Parameter(name = "AcceptanceTester", value="$I") - * @group functionalTest * @param AcceptanceTester $I * @return void */ diff --git a/dev/tests/verification/Resources/DataReplacementCest.txt b/dev/tests/verification/Resources/DataReplacementCest.txt new file mode 100644 index 000000000..f0cb52be1 --- /dev/null +++ b/dev/tests/verification/Resources/DataReplacementCest.txt @@ -0,0 +1,49 @@ +fillField("#selector", "StringBefore John StringAfter"); + $I->fillField("#John", "input"); + $I->dragAndDrop("#John", "Doe"); + $I->conditionalClick("Doe", "#John", true); + $I->amOnUrl("John.html"); + $I->searchAndMultiSelectOption("#selector", ["John", "Doe"]); + $I->fillField("#selector", "StringBefore ".msq("uniqueData")."John StringAfter"); + $I->fillField("#".msq("uniqueData")."John", "input"); + $I->dragAndDrop("#".msq("uniqueData")."John", msq("uniqueData")."John"); + $I->conditionalClick(msq("uniqueData")."John", "#".msq("uniqueData")."John", true); + $I->amOnUrl(msq("uniqueData")."John.html"); + $I->searchAndMultiSelectOption("#selector", [msq("uniqueData")."John", "Doe"]); + $I->fillField("#selector", "StringBefore Doe".msq("uniqueData")." StringAfter"); + $I->fillField("#Doe".msq("uniqueData"), "input"); + $I->dragAndDrop("#Doe".msq("uniqueData"), "Doe".msq("uniqueData")); + $I->conditionalClick("Doe".msq("uniqueData"), "#Doe".msq("uniqueData"), true); + $I->amOnUrl("Doe".msq("uniqueData").".html"); + $I->searchAndMultiSelectOption("#selector", ["John", "Doe".msq("uniqueData")]); + $I->searchAndMultiSelectOption("#selector", [msq("uniqueData")."John", "Doe".msq("uniqueData")]); + } +} diff --git a/dev/tests/verification/Resources/LocatorFunctionCest.txt b/dev/tests/verification/Resources/LocatorFunctionCest.txt new file mode 100644 index 000000000..b716443c0 --- /dev/null +++ b/dev/tests/verification/Resources/LocatorFunctionCest.txt @@ -0,0 +1,46 @@ +amGoingTo("create entity that has the mergeKey: data"); + $ReplacementPerson = DataObjectHandler::getInstance()->getObject("ReplacementPerson"); + $data = new DataPersistenceHandler($ReplacementPerson); + $data->createEntity(); + $I->click(Locator::contains("'label'", "'Name'")); + $I->click(Locator::contains("'label'", "'Name'")); + $I->click(Locator::find("'img'", ['title' => 'diagram'])); + $I->click(Locator::contains("string", "'Name'")); + $I->click(Locator::contains("John", "'Name'")); + $I->click(Locator::contains($data->getCreatedDataByName('key'), "'Name'")); + $I->click(Locator::contains("string1", "string2")); + $I->click(Locator::contains("John", "Doe")); + $I->click(Locator::contains($data->getCreatedDataByName('key1'), $data->getCreatedDataByName('key2'))); + $I->click(Locator::contains("string1", "John")); + $I->click(Locator::contains("string1", $data->getCreatedDataByName('key1'))); + $I->click(Locator::contains("John", $data->getCreatedDataByName('key1'))); + } +} diff --git a/dev/tests/verification/Resources/MergeFunctionalCest.txt b/dev/tests/verification/Resources/MergeFunctionalCest.txt index 9645490bb..36fc00b80 100644 --- a/dev/tests/verification/Resources/MergeFunctionalCest.txt +++ b/dev/tests/verification/Resources/MergeFunctionalCest.txt @@ -5,6 +5,7 @@ use Magento\FunctionalTestingFramework\AcceptanceTester; use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; +use \Codeception\Util\Locator; use Yandex\Allure\Adapter\Annotation\Features; use Yandex\Allure\Adapter\Annotation\Stories; use Yandex\Allure\Adapter\Annotation\Title; @@ -16,7 +17,7 @@ use Yandex\Allure\Adapter\Annotation\TestCaseId; /** * @Severity(level = SeverityLevel::CRITICAL) - * @Title("Title") + * @Title("A Functional Cest") * @group mergeTest * @Features({"Merge Functional Cest"}) * @Stories({"MQE-433"}) diff --git a/dev/tests/verification/Resources/PageReplacementCest.txt b/dev/tests/verification/Resources/PageReplacementCest.txt new file mode 100644 index 000000000..bfb459b5b --- /dev/null +++ b/dev/tests/verification/Resources/PageReplacementCest.txt @@ -0,0 +1,42 @@ +amGoingTo("create entity that has the mergeKey: datakey"); + $simpleData = DataObjectHandler::getInstance()->getObject("simpleData"); + $datakey = new DataPersistenceHandler($simpleData); + $datakey->createEntity(); + $I->amOnPage("/page.html"); + $I->amOnPage("/StringLiteral/page.html"); + $I->amOnPage("/John/page.html"); + $I->amOnPage("/" . $datakey->getCreatedDataByName('firstname') . "/page.html"); + $I->amOnPage("/StringLiteral1/StringLiteral2.html"); + $I->amOnPage("/John/StringLiteral2.html"); + $I->amOnPage("/John/" . $datakey->getCreatedDataByName('firstname') . ".html"); + $I->amOnPage("/" . $datakey->getCreatedDataByName('firstname') . "/StringLiteral2.html"); + } +} diff --git a/dev/tests/verification/Resources/ParameterArrayCest.txt b/dev/tests/verification/Resources/ParameterArrayCest.txt index 1e4ae4b39..c07354af1 100644 --- a/dev/tests/verification/Resources/ParameterArrayCest.txt +++ b/dev/tests/verification/Resources/ParameterArrayCest.txt @@ -5,6 +5,7 @@ use Magento\FunctionalTestingFramework\AcceptanceTester; use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; +use \Codeception\Util\Locator; use Yandex\Allure\Adapter\Annotation\Features; use Yandex\Allure\Adapter\Annotation\Stories; use Yandex\Allure\Adapter\Annotation\Title; @@ -33,7 +34,7 @@ class ParameterArrayCest $I->searchAndMultiSelectOption("#selector", [msq("simpleParamData")."prename"]); $I->searchAndMultiSelectOption("#selector", ["postname".msq("simpleParamData")]); $I->searchAndMultiSelectOption("#selector", [$simpleDataKey->getCreatedDataByName('name')]); - $I->searchAndMultiSelectOption("#selector", ["name", "" . $simpleDataKey->getCreatedDataByName('name')]); + $I->searchAndMultiSelectOption("#selector", ["name", $simpleDataKey->getCreatedDataByName('name')]); $I->searchAndMultiSelectOption("#selector", ['someKey' => $simpleDataKey->getCreatedDataByName('name')]); $I->searchAndMultiSelectOption("#selector", ['someKey' => "name"]); $I->searchAndMultiSelectOption("#selector", ['someKey' => msq("simpleParamData")."prename"]); diff --git a/dev/tests/verification/Resources/PersistedReplacementCest.txt b/dev/tests/verification/Resources/PersistedReplacementCest.txt index d52b74930..4ff8d853e 100644 --- a/dev/tests/verification/Resources/PersistedReplacementCest.txt +++ b/dev/tests/verification/Resources/PersistedReplacementCest.txt @@ -5,6 +5,7 @@ use Magento\FunctionalTestingFramework\AcceptanceTester; use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; +use \Codeception\Util\Locator; use Yandex\Allure\Adapter\Annotation\Features; use Yandex\Allure\Adapter\Annotation\Stories; use Yandex\Allure\Adapter\Annotation\Title; @@ -38,34 +39,17 @@ class PersistedReplacementCest */ public function PersistedReplacementTest(AcceptanceTester $I) { - $I->amGoingTo("create entity that has the mergeKey: testScopeData"); - $ReplacementPerson = DataObjectHandler::getInstance()->getObject("ReplacementPerson"); - $testScopeData = new DataPersistenceHandler($ReplacementPerson); - $testScopeData->createEntity(); - $I->amGoingTo("create entity that has the mergeKey: uniqueData"); - $UniquePerson = DataObjectHandler::getInstance()->getObject("UniquePerson"); - $uniqueData = new DataPersistenceHandler($UniquePerson); - $uniqueData->createEntity(); - $I->amOnPage("/success/success2.html"); - $I->amOnPage($testScopeData->getCreatedDataByName('firstname') . ".html"); - $I->amOnPage($this->createData1->getCreatedDataByName('firstname') . ".html"); - $I->amOnPage("/" . $testScopeData->getCreatedDataByName('firstname') . "/" . $testScopeData->getCreatedDataByName('lastname') . ".html"); - $I->amOnPage("/" . $this->createData1->getCreatedDataByName('firstname') . "/" . $this->createData1->getCreatedDataByName('lastname') . ".html"); - $I->click("#element ." . $testScopeData->getCreatedDataByName('firstname')); - $I->click("#" . $testScopeData->getCreatedDataByName('firstname') . " .success"); - $I->click("#John-Doe ." . $testScopeData->getCreatedDataByName('lastname')); - $I->click("#" . $testScopeData->getCreatedDataByName('firstname') . " ." . $testScopeData->getCreatedDataByName('lastname')); - $I->click("#" . $this->createData1->getCreatedDataByName('firstname') . " ." . $this->createData1->getCreatedDataByName('lastname')); - $I->fillField("#sample", "Hello " . $testScopeData->getCreatedDataByName('firstname') . " " . $testScopeData->getCreatedDataByName('lastname')); - $I->fillField("#sample", "Hello " . $this->createData1->getCreatedDataByName('firstname') . " " . $this->createData1->getCreatedDataByName('lastname')); - $I->searchAndMultiSelectOption("#selector", [$testScopeData->getCreatedDataByName('lastname')]); - $I->searchAndMultiSelectOption("#selector", [$this->createData1->getCreatedDataByName('lastname')]); - $I->amOnPage($uniqueData->getCreatedDataByName('firstname') . ".html"); - $I->amOnPage("/" . $uniqueData->getCreatedDataByName('firstname') . "/" . $uniqueData->getCreatedDataByName('lastname') . ".html"); - $I->click("#element ." . $uniqueData->getCreatedDataByName('firstname')); - $I->click("#" . $uniqueData->getCreatedDataByName('firstname') . " .success"); - $I->click("#" . $uniqueData->getCreatedDataByName('firstname')); - $I->dragAndDrop($uniqueData->getCreatedDataByName('firstname'), $uniqueData->getCreatedDataByName('firstname')); - $I->dragAndDrop("#element ." . $uniqueData->getCreatedDataByName('firstname'), "#" . $uniqueData->getCreatedDataByName('firstname') . " .success"); + $I->amGoingTo("create entity that has the mergeKey: createdData"); + $simpleData = DataObjectHandler::getInstance()->getObject("simpleData"); + $createdData = new DataPersistenceHandler($simpleData); + $createdData->createEntity(); + $I->fillField("#selector", "StringBefore " . $createdData->getCreatedDataByName('firstname') . " StringAfter"); + $I->fillField("#" . $createdData->getCreatedDataByName('firstname'), "input"); + $I->dragAndDrop("#" . $createdData->getCreatedDataByName('firstname'), $createdData->getCreatedDataByName('lastname')); + $I->conditionalClick($createdData->getCreatedDataByName('lastname'), "#" . $createdData->getCreatedDataByName('firstname'), true); + $I->amOnUrl($createdData->getCreatedDataByName('firstname') . ".html"); + $I->searchAndMultiSelectOption("#selector", [$createdData->getCreatedDataByName('firstname'), $createdData->getCreatedDataByName('lastname')]); + $I->fillField("#selector", "John " . $createdData->getCreatedDataByName('firstname') . " stringLiteral"); + $I->searchAndMultiSelectOption("#selector", [$createdData->getCreatedDataByName('firstname'), "John", "stringLiteral"]); } } diff --git a/dev/tests/verification/Resources/SectionReplacementCest.txt b/dev/tests/verification/Resources/SectionReplacementCest.txt new file mode 100644 index 000000000..333f5ac4f --- /dev/null +++ b/dev/tests/verification/Resources/SectionReplacementCest.txt @@ -0,0 +1,60 @@ +click("#element"); + $I->click("#foo"); + $I->waitForPageLoad(30); + $I->click("#element .stringLiteral"); + $I->click("#stringLiteral1 .stringLiteral2"); + $I->click("#stringLiteral1-stringLiteral2 .stringLiteral3"); + $I->click("#stringLiteral1-stringLiteral2 .stringLiteral1 [stringLiteral3]"); + $I->click("#element .John"); + $I->click("#John .Doe"); + $I->click("#John-Doe .Tiberius"); + $I->click("#John-Doe .John [Tiberius]"); + $I->click("#element .".msq("uniqueData")."John"); + $I->click("#".msq("uniqueData")."John .stringLiteral2"); + $I->click("#".msq("uniqueData")."John-stringLiteral2 .stringLiteral3"); + $I->click("#".msq("uniqueData")."John-stringLiteral2 ."); + $I->click("#element .Doe".msq("uniqueData")); + $I->click("#Doe".msq("uniqueData")." .stringLiteral2"); + $I->click("#Doe".msq("uniqueData")."-stringLiteral2 .stringLiteral3"); + $I->click("#Doe".msq("uniqueData")."-stringLiteral2 .Doe"); + $I->amGoingTo("create entity that has the mergeKey: createdData"); + $simpleData = DataObjectHandler::getInstance()->getObject("simpleData"); + $createdData = new DataPersistenceHandler($simpleData); + $createdData->createEntity(); + $I->click("#element ." . $createdData->getCreatedDataByName('firstname')); + $I->click("#" . $createdData->getCreatedDataByName('firstname') . " .stringLiteral2"); + $I->click("#" . $createdData->getCreatedDataByName('firstname') . "-stringLiteral2 .stringLiteral3"); + $I->click("#" . $createdData->getCreatedDataByName('firstname') . "-stringLiteral2 ." . $createdData->getCreatedDataByName('firstname') . " [stringLiteral3]"); + $I->click("#stringLiteral1-" . $createdData->getCreatedDataByName('firstname') . " .John"); + $I->click("#stringLiteral1-" . $createdData->getCreatedDataByName('firstname') . " .".msq("uniqueData")."John"); + $I->click("#stringLiteral1-" . $createdData->getCreatedDataByName('firstname') . " .Doe".msq("uniqueData")); + } +} diff --git a/dev/tests/verification/Resources/testSuiteGeneration1.txt b/dev/tests/verification/Resources/TestSuiteGeneration1.txt similarity index 100% rename from dev/tests/verification/Resources/testSuiteGeneration1.txt rename to dev/tests/verification/Resources/TestSuiteGeneration1.txt diff --git a/dev/tests/verification/TestModule/Cest/AssertCest.xml b/dev/tests/verification/TestModule/Cest/AssertCest.xml new file mode 100644 index 000000000..9444da9f6 --- /dev/null +++ b/dev/tests/verification/TestModule/Cest/AssertCest.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/tests/verification/TestModule/Cest/basicFunctionalCest.xml b/dev/tests/verification/TestModule/Cest/BasicFunctionalCest.xml similarity index 100% rename from dev/tests/verification/TestModule/Cest/basicFunctionalCest.xml rename to dev/tests/verification/TestModule/Cest/BasicFunctionalCest.xml diff --git a/dev/tests/verification/TestModule/Cest/DataReplacementCest.xml b/dev/tests/verification/TestModule/Cest/DataReplacementCest.xml new file mode 100644 index 000000000..1e33dd731 --- /dev/null +++ b/dev/tests/verification/TestModule/Cest/DataReplacementCest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tests/verification/TestModule/Cest/LocatorFunctionCest.xml b/dev/tests/verification/TestModule/Cest/LocatorFunctionCest.xml new file mode 100644 index 000000000..497320d15 --- /dev/null +++ b/dev/tests/verification/TestModule/Cest/LocatorFunctionCest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tests/verification/TestModule/Cest/PageReplacementCest.xml b/dev/tests/verification/TestModule/Cest/PageReplacementCest.xml new file mode 100644 index 000000000..26ad49337 --- /dev/null +++ b/dev/tests/verification/TestModule/Cest/PageReplacementCest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tests/verification/TestModule/Cest/PersistedReplacementCest.xml b/dev/tests/verification/TestModule/Cest/PersistedReplacementCest.xml index 48cff411e..663c51ef7 100644 --- a/dev/tests/verification/TestModule/Cest/PersistedReplacementCest.xml +++ b/dev/tests/verification/TestModule/Cest/PersistedReplacementCest.xml @@ -13,55 +13,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/dev/tests/verification/TestModule/Cest/SectionReplacementCest.xml b/dev/tests/verification/TestModule/Cest/SectionReplacementCest.xml new file mode 100644 index 000000000..ca91fef27 --- /dev/null +++ b/dev/tests/verification/TestModule/Cest/SectionReplacementCest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/tests/verification/TestModule/Data/ReplacementData.xml b/dev/tests/verification/TestModule/Data/ReplacementData.xml new file mode 100644 index 000000000..de25aead8 --- /dev/null +++ b/dev/tests/verification/TestModule/Data/ReplacementData.xml @@ -0,0 +1,21 @@ + + + + + + + John + Doe + Tiberius + + + John + Doe + + diff --git a/dev/tests/verification/TestModule/Metadata/placeholder.txt b/dev/tests/verification/TestModule/Metadata/Placeholder.txt similarity index 100% rename from dev/tests/verification/TestModule/Metadata/placeholder.txt rename to dev/tests/verification/TestModule/Metadata/Placeholder.txt diff --git a/dev/tests/verification/TestModule/Page/SamplePage.xml b/dev/tests/verification/TestModule/Page/SamplePage.xml index 02eca33c9..22b85737d 100644 --- a/dev/tests/verification/TestModule/Page/SamplePage.xml +++ b/dev/tests/verification/TestModule/Page/SamplePage.xml @@ -11,4 +11,13 @@
+ +
+ + +
+ + +
+ diff --git a/dev/tests/verification/TestModule/Section/LocatorFunctionSection.xml b/dev/tests/verification/TestModule/Section/LocatorFunctionSection.xml new file mode 100644 index 000000000..1acb939e1 --- /dev/null +++ b/dev/tests/verification/TestModule/Section/LocatorFunctionSection.xml @@ -0,0 +1,19 @@ + + + + +
+ + + + + + +
+
diff --git a/dev/tests/verification/TestModule/Section/SampleSection.xml b/dev/tests/verification/TestModule/Section/SampleSection.xml index 211af228d..63a525886 100644 --- a/dev/tests/verification/TestModule/Section/SampleSection.xml +++ b/dev/tests/verification/TestModule/Section/SampleSection.xml @@ -9,9 +9,11 @@
+ +
diff --git a/dev/tests/verification/TestModule/Section/zMergeSection.xml b/dev/tests/verification/TestModule/Section/ZMergeSection.xml similarity index 100% rename from dev/tests/verification/TestModule/Section/zMergeSection.xml rename to dev/tests/verification/TestModule/Section/ZMergeSection.xml diff --git a/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php b/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php index eae2dad70..0b3f8844c 100644 --- a/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php +++ b/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php @@ -32,7 +32,6 @@ public function testActionGroupFunctionalCest() $this->runComparisonTest(self::ACTION_GROUP_FUNCTIONAL_CEST); } - /** * Generate a Cest by name and assert that it equals the corresponding .txt source of truth * @@ -51,7 +50,6 @@ private function runComparisonTest($cestName) $this->assertTrue(file_exists($cestFile)); - $this->assertFileEquals( self::RESOURCES_PATH . DIRECTORY_SEPARATOR . $cestName . ".txt", $cestFile diff --git a/dev/tests/verification/Tests/PersistedReplacementGenerationTest.php b/dev/tests/verification/Tests/AssertGenerationTest.php similarity index 63% rename from dev/tests/verification/Tests/PersistedReplacementGenerationTest.php rename to dev/tests/verification/Tests/AssertGenerationTest.php index b95afc99d..ea0857228 100644 --- a/dev/tests/verification/Tests/PersistedReplacementGenerationTest.php +++ b/dev/tests/verification/Tests/AssertGenerationTest.php @@ -9,29 +9,29 @@ use Magento\FunctionalTestingFramework\Util\TestGenerator; use PHPUnit\Framework\TestCase; -class PersistedReplacementGenerationTest extends TestCase +class AssertGenerationTest extends TestCase { - const PERSISTED_REPLACEMENT_CEST = 'PersistedReplacementCest'; + const BASIC_ASSERT_CEST = 'AssertCest'; const RESOURCES_PATH = __DIR__ . '/../Resources'; /** - * Tests flat generation of a hardcoded cest file with no external references. + * Tests assert generation. */ - public function testPersistedReplacementGeneration() + public function testAssertGeneration() { - $cest = CestObjectHandler::getInstance()->getObject(self::PERSISTED_REPLACEMENT_CEST); + $cest = CestObjectHandler::getInstance()->getObject(self::BASIC_ASSERT_CEST); $test = TestGenerator::getInstance(null, [$cest]); $test->createAllCestFiles(); $cestFile = $test->getExportDir() . DIRECTORY_SEPARATOR . - self::PERSISTED_REPLACEMENT_CEST . + self::BASIC_ASSERT_CEST . ".php"; $this->assertTrue(file_exists($cestFile)); $this->assertFileEquals( - self::RESOURCES_PATH . DIRECTORY_SEPARATOR . self::PERSISTED_REPLACEMENT_CEST . ".txt", + self::RESOURCES_PATH . DIRECTORY_SEPARATOR . self::BASIC_ASSERT_CEST . ".txt", $cestFile ); } diff --git a/dev/tests/verification/Tests/LocatorFunctionGenerationTest.php b/dev/tests/verification/Tests/LocatorFunctionGenerationTest.php new file mode 100644 index 000000000..e7d9648b1 --- /dev/null +++ b/dev/tests/verification/Tests/LocatorFunctionGenerationTest.php @@ -0,0 +1,38 @@ +getObject(self::LOCATOR_FUNCTION_CEST); + $test = TestGenerator::getInstance(null, [$cest]); + $test->createAllCestFiles(); + + $cestFile = $test->getExportDir() . + DIRECTORY_SEPARATOR . + self::LOCATOR_FUNCTION_CEST . + ".php"; + + $this->assertTrue(file_exists($cestFile)); + + $this->assertFileEquals( + self::RESOURCES_PATH . DIRECTORY_SEPARATOR . self::LOCATOR_FUNCTION_CEST . ".txt", + $cestFile + ); + } +} diff --git a/dev/tests/verification/Tests/ReferenceReplacementGenerationTest.php b/dev/tests/verification/Tests/ReferenceReplacementGenerationTest.php new file mode 100644 index 000000000..a0ee240b3 --- /dev/null +++ b/dev/tests/verification/Tests/ReferenceReplacementGenerationTest.php @@ -0,0 +1,75 @@ +runComparisonTest(self::DATA_REPLACEMENT_CEST); + } + + /** + * Tests replacement of $data.key$ references. + */ + public function testPersistedeferenceReplacementCest() + { + $this->runComparisonTest(self::PERSISTED_REPLACEMENT_CEST); + } + + /** + * Tests replacement of {{page.url}} references. Includes parameterized urls. + */ + public function testPageReferenceReplacementCest() + { + $this->runComparisonTest(self::PAGE_REPLACEMENT_CEST); + } + + /** + * Tests replacement of {{Section.Element}} references. Includes parameterized elements. + */ + public function testSectionReferenceReplacementCest() + { + $this->runComparisonTest(self::SECTION_REPLACEMENT_CEST); + } + + /** + * Instantiates CestObjectHandler and TestGenerator, then compares given cest against flat txt equivalent. + * @param string $cestName + */ + private function runComparisonTest($cestName) + { + $cest = CestObjectHandler::getInstance()->getObject($cestName); + $test = TestGenerator::getInstance(null, [$cest]); + $test->createAllCestFiles(); + + $cestFile = $test->getExportDir() . + DIRECTORY_SEPARATOR . + $cestName . + ".php"; + + $this->assertTrue(file_exists($cestFile)); + + $this->assertFileEquals( + self::RESOURCES_PATH . DIRECTORY_SEPARATOR . $cestName . ".txt", + $cestFile + ); + } +} diff --git a/dev/tests/verification/Tests/SuiteGenerationTest.php b/dev/tests/verification/Tests/SuiteGenerationTest.php index fc34b9af1..947069ad9 100644 --- a/dev/tests/verification/Tests/SuiteGenerationTest.php +++ b/dev/tests/verification/Tests/SuiteGenerationTest.php @@ -19,7 +19,6 @@ class SuiteGenerationTest extends TestCase private static $YML_EXISTS_FLAG = false; private static $TEST_GROUPS = []; - public static function setUpBeforeClass() { if (file_exists(self::CONFIG_YML_FILE)) { @@ -56,8 +55,8 @@ public function testSuiteGeneration1() $groupName . DIRECTORY_SEPARATOR . TestManifest::TEST_MANIFEST_FILENAME; - $expectedManifest = self::RESOURCES_DIR . DIRECTORY_SEPARATOR . __FUNCTION__ . ".txt"; - $this->assertFileEquals($expectedManifest, $actualManifest); + $expectedManifest = self::RESOURCES_DIR . DIRECTORY_SEPARATOR . "TestSuiteGeneration1.txt"; + $this->assertFileEquals($expectedManifest, $actualManifest, '', true, true); } public static function tearDownAfterClass() diff --git a/etc/di.xml b/etc/di.xml index ad5b0db84..c6e77e5b8 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -208,7 +208,7 @@ createDataKey createDataKey createDataKey - mergeKey + mergeKey *Cest.xml Cest @@ -218,9 +218,9 @@ - mergeKey - mergeKey - mergeKey + mergeKey + mergeKey + mergeKey name name createDataKey @@ -242,6 +242,7 @@ /config/cest/annotations/description /config/cest/annotations/severity /config/cest/annotations/testCaseId + /config/cest/annotations/useCaseId /config/cest/annotations/group /config/cest/annotations/return /config/cest/test/annotations/features @@ -250,6 +251,7 @@ /config/cest/test/annotations/description /config/cest/test/annotations/severity /config/cest/test/annotations/testCaseId + /config/cest/test/annotations/useCaseId /config/cest/test/annotations/group /config/cest/test/annotations/env /config/cest/test/annotations/return @@ -284,7 +286,7 @@ name name - mergeKey + mergeKey *ActionGroup.xml ActionGroup @@ -294,7 +296,7 @@ - mergeKey + mergeKey name name diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php index 9dda26324..0fb40aa7d 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php @@ -28,7 +28,6 @@ class OperationDefinitionObjectHandler implements ObjectHandlerInterface const ENTITY_OPERATION_HEADER_PARAM = 'param'; const ENTITY_OPERATION_HEADER_VALUE = 'value'; const ENTITY_OPERATION_URL_PARAM = 'param'; - const ENTITY_OPERATION_URL_PARAM_TYPE = 'type'; const ENTITY_OPERATION_URL_PARAM_KEY = 'key'; const ENTITY_OPERATION_URL_PARAM_VALUE = 'value'; const ENTITY_OPERATION_ENTRY = 'field'; @@ -156,8 +155,7 @@ private function initDataDefinitions() if (array_key_exists(OperationDefinitionObjectHandler::ENTITY_OPERATION_URL_PARAM, $opDefArray)) { foreach ($opDefArray[OperationDefinitionObjectHandler::ENTITY_OPERATION_URL_PARAM] as $paramEntry) { - $params[$paramEntry[OperationDefinitionObjectHandler::ENTITY_OPERATION_URL_PARAM_TYPE]] - [$paramEntry[OperationDefinitionObjectHandler::ENTITY_OPERATION_URL_PARAM_KEY]] = + $params[$paramEntry[OperationDefinitionObjectHandler::ENTITY_OPERATION_URL_PARAM_KEY]] = $paramEntry[OperationDefinitionObjectHandler::ENTITY_OPERATION_URL_PARAM_VALUE]; } } diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php index 2504ada77..c94ce58ae 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/CurlHandler.php @@ -106,9 +106,7 @@ public function executeRequest($dependentEntities) $successRegex = null; $returnRegex = null; - if ($this->operation == 'update') { - $entities = array_merge($dependentEntities, [$this->entityObject]); - } elseif ((null !== $dependentEntities) && is_array($dependentEntities)) { + if ((null !== $dependentEntities) && is_array($dependentEntities)) { $entities = array_merge([$this->entityObject], $dependentEntities); } else { $entities = [$this->entityObject]; diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/DataPersistenceHandler.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/DataPersistenceHandler.php index d69595f7c..d28d87300 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/DataPersistenceHandler.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/DataPersistenceHandler.php @@ -7,6 +7,7 @@ namespace Magento\FunctionalTestingFramework\DataGenerator\Persist; use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; +use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler; /** * Class DataPersistenceHandler @@ -80,17 +81,24 @@ public function createEntity($storeCode = null) /** * Function which executes a put request based on specific operation metadata. * + * @param string $updateDataName + * @param array $updateDependentObjects * @param string $storeCode * @return void */ - public function updateEntity($storeCode = null) + public function updateEntity($updateDataName, $updateDependentObjects = [], $storeCode = null) { if (!empty($storeCode)) { $this->storeCode = $storeCode; } - $curlHandler = new CurlHandler('update', $this->entityObject, $this->storeCode); - $result = $curlHandler->executeRequest($this->dependentObjects); + + foreach ($updateDependentObjects as $dependentObject) { + $this->dependentObjects[] = $dependentObject->getCreatedObject(); + } + $updateEntityObject = DataObjectHandler::getInstance()->getObject($updateDataName); + $curlHandler = new CurlHandler('update', $updateEntityObject, $this->storeCode); + $result = $curlHandler->executeRequest(array_merge($this->dependentObjects, [$this->createdObject])); $this->setCreatedObject( $result, null, diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd b/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd index 7126fa67e..7d4cc80d3 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd @@ -72,7 +72,6 @@ - diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php index f2004b1ee..b6e6e2800 100644 --- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php +++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php @@ -41,7 +41,13 @@ class MagentoWebDriver extends WebDriver { use AttachmentSupport; - public static $loadingMask = '.loading-mask'; + public static $loadingMasksLocators = [ + '//div[contains(@class, "loading-mask")]', + '//div[contains(@class, "admin_data-grid-loading-mask")]', + '//div[contains(@class, "admin__data-grid-loading-mask")]', + '//div[contains(@class, "admin__form-loading-mask")]', + '//div[@data-role="spinner"]' + ]; /** * The module required fields, to be set in the suite .yml configuration file. @@ -189,17 +195,20 @@ public function waitForPageLoad($timeout = 15) { $this->waitForJS('return document.readyState == "complete"', $timeout); $this->waitForAjaxLoad($timeout); - $this->waitForElementNotVisible('.loading-mask', 30); - $this->waitForElementNotVisible('.admin_data-grid-loading-mask', 30); - $this->waitForElementNotVisible('.admin__form-loading-mask', 30); + $this->waitForLoadingMaskToDisappear(); } /** - * Wait for the Loading mask to disappear. + * Wait for all visible loading masks to disappear. Gets all elements by mask selector, then loops over them. */ public function waitForLoadingMaskToDisappear() { - $this->waitForElementNotVisible(self::$loadingMask, 30); + foreach( self::$loadingMasksLocators as $maskLocator) { + $loadingMaskElements = $this->_findElements($maskLocator); + for ($i = 1; $i <= count($loadingMaskElements); $i++) { + $this->waitForElementNotVisible("{$maskLocator}[{$i}]", 30); + } + } } /** diff --git a/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php b/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php index 8bd5863a4..a39db4c69 100644 --- a/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php +++ b/src/Magento/FunctionalTestingFramework/Page/Handlers/SectionObjectHandler.php @@ -21,6 +21,7 @@ class SectionObjectHandler implements ObjectHandlerInterface const SUB_TYPE = 'element'; const ELEMENT_TYPE_ATTR = 'type'; const ELEMENT_SELECTOR_ATTR = 'selector'; + const ELEMENT_LOCATOR_FUNC_ATTR = 'locatorFunction'; const ELEMENT_TIMEOUT_ATTR = 'timeout'; const ELEMENT_PARAMETERIZED = 'parameterized'; @@ -109,7 +110,8 @@ private function initSectionObjects() $elements = []; foreach ($sectionData[SectionObjectHandler::SUB_TYPE] as $elementName => $elementData) { $elementType = $elementData[SectionObjectHandler::ELEMENT_TYPE_ATTR]; - $elementSelector = $elementData[SectionObjectHandler::ELEMENT_SELECTOR_ATTR]; + $elementSelector = $elementData[SectionObjectHandler::ELEMENT_SELECTOR_ATTR] ?? null; + $elementLocatorFunc = $elementData[SectionObjectHandler::ELEMENT_LOCATOR_FUNC_ATTR] ?? null; $elementTimeout = $elementData[SectionObjectHandler::ELEMENT_TIMEOUT_ATTR] ?? null; $elementParameterized = $elementData[SectionObjectHandler::ELEMENT_PARAMETERIZED] ?? false; @@ -117,6 +119,7 @@ private function initSectionObjects() $elementName, $elementType, $elementSelector, + $elementLocatorFunc, $elementTimeout, $elementParameterized ); diff --git a/src/Magento/FunctionalTestingFramework/Page/Objects/ElementObject.php b/src/Magento/FunctionalTestingFramework/Page/Objects/ElementObject.php index b55911b61..f8738bc93 100644 --- a/src/Magento/FunctionalTestingFramework/Page/Objects/ElementObject.php +++ b/src/Magento/FunctionalTestingFramework/Page/Objects/ElementObject.php @@ -5,6 +5,8 @@ */ namespace Magento\FunctionalTestingFramework\Page\Objects; +use Magento\FunctionalTestingFramework\Exceptions\XmlException; + /** * Class ElementObject */ @@ -33,6 +35,13 @@ class ElementObject */ private $selector; + /** + * Section element locatorFunction + * + * @var string + */ + private $locatorFunction; + /** * Section element timeout * @@ -52,14 +61,26 @@ class ElementObject * @param string $name * @param string $type * @param string $selector + * @param string $locatorFunction * @param string $timeout * @param bool $parameterized + * @throws XmlException */ - public function __construct($name, $type, $selector, $timeout, $parameterized) + public function __construct($name, $type, $selector, $locatorFunction, $timeout, $parameterized) { + if ($selector != null && $locatorFunction != null) { + throw new XmlException("Element '{$name}' cannot have both a selector and a locatorFunction."); + } elseif ($selector == null && $locatorFunction == null) { + throw new XmlException("Element '{$name}' must have either a selector or a locatorFunction.'"); + } + $this->name = $name; $this->type = $type; $this->selector = $selector; + $this->locatorFunction = $locatorFunction; + if (strpos($locatorFunction, "Locator::") === false) { + $this->locatorFunction = "Locator::" . $locatorFunction; + } $this->timeout = $timeout; $this->parameterized = $parameterized; } @@ -94,6 +115,16 @@ public function getSelector() return $this->selector; } + /** + * Getter for the locatorFunction of an element + * + * @return string + */ + public function getLocatorFunction() + { + return $this->locatorFunction; + } + /** * Returns an integer representing an element's timeout * diff --git a/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd b/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd index 4fdeba173..3c95a5ffc 100644 --- a/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd +++ b/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd @@ -64,10 +64,17 @@ - + - Selector of the element. + Selector of the element. Optional due to being able to use either this or locatorFunction. + + + + + + + LocatorFunction of an element, substitute for a selector. diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index 11c0f05df..40feb93de 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -6,6 +6,7 @@ namespace Magento\FunctionalTestingFramework\Test\Objects; +use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException; use Magento\FunctionalTestingFramework\Test\Util\ActionMergeUtil; /** @@ -65,12 +66,23 @@ public function __construct($name, $arguments, $actions) * @param array $arguments * @param string $actionReferenceKey * @return array + * @throws TestReferenceException */ public function getSteps($arguments, $actionReferenceKey) { $mergeUtil = new ActionMergeUtil($this->name, "ActionGroup"); $args = $this->arguments; - + $emptyArguments = array_keys($args, null, true); + if (!empty($emptyArguments) && $arguments !== null) { + $diff = array_diff($emptyArguments, array_keys($arguments)); + if (!empty($diff)) { + $error = 'Argument(s) missed (' . implode(", ", $diff) . ') for actionGroup "' . $this->name . '"'; + throw new TestReferenceException($error); + } + } elseif (!empty($emptyArguments)) { + $error = 'Not enough arguments given for actionGroup "' . $this->name . '"'; + throw new TestReferenceException($error); + } if ($arguments) { $args = array_merge($args, $arguments); } diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php index 9647d0f34..821c06efc 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php @@ -22,6 +22,7 @@ class ActionObject const DATA_ENABLED_ATTRIBUTES = ["userInput", "parameterArray"]; const SELECTOR_ENABLED_ATTRIBUTES = ['selector', 'dependentSelector', "selector1", "selector2"]; const MERGE_ACTION_ORDER_AFTER = 'after'; + const MERGE_ACTION_ORDER_BEFORE = 'before'; const ACTION_ATTRIBUTE_URL = 'url'; const ACTION_ATTRIBUTE_SELECTOR = 'selector'; const ACTION_ATTRIBUTE_VARIABLE_REGEX_PARAMETER = '/\(.+\)/'; @@ -83,10 +84,15 @@ class ActionObject * @param string $type * @param array $actionAttributes * @param string|null $linkedAction - * @param int $order + * @param string $order */ - public function __construct($mergeKey, $type, $actionAttributes, $linkedAction = null, $order = 0) - { + public function __construct( + $mergeKey, + $type, + $actionAttributes, + $linkedAction = null, + $order = ActionObject::MERGE_ACTION_ORDER_BEFORE + ) { $this->mergeKey = $mergeKey; $this->type = $type; $this->actionAttributes = $actionAttributes; @@ -323,7 +329,9 @@ private function findAndReplaceReferences($objectHandler, $inputString) throw new TestReferenceException("Could not resolve entity reference " . $inputString); } $parameterized = $obj->getElement($objField)->isParameterized(); - $replacement = $obj->getElement($objField)->getSelector(); + // If no Selector is defined, assume element has LocatorFunction + $replacement = $obj->getElement($objField)->getSelector() ?: + $obj->getElement($objField)->getLocatorFunction(); $this->timeout = $obj->getElement($objField)->getTimeout(); break; case (get_class($obj) == EntityDataObject::class): @@ -351,7 +359,7 @@ private function findAndReplaceReferences($objectHandler, $inputString) throw new TestReferenceException("Could not resolve entity reference " . $inputString); } - //If Page or Section's Element is has parameterized = true attribute, attempt to do parameter replacement. + // If Page or Section's Element has the parameterized = true attribute, attempt to do parameter replacement if ($parameterized) { $parameterList = $this->stripAndReturnParameters($match); $replacement = $this->matchParameterReferences($replacement, $parameterList); @@ -373,6 +381,7 @@ private function findAndReplaceReferences($objectHandler, $inputString) private function matchParameterReferences($reference, $parameters) { preg_match_all('/{{[\w.]+}}/', $reference, $varMatches); + $varMatches[0] = array_unique($varMatches[0]); if (count($varMatches[0]) > count($parameters)) { if (is_array($parameters)) { $parametersGiven = implode(",", $parameters); diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php index 5b4f45d2a..8489a3828 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php +++ b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php @@ -77,7 +77,7 @@ private function extractArguments($arguments) ); foreach ($argData as $argName => $argValue) { - $parsedArguments[$argName] = $argValue[self::DEFAULT_VALUE]; + $parsedArguments[$argName] = $argValue[self::DEFAULT_VALUE] ?? null; } return $parsedArguments; diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/TestNameValidationUtil.php b/src/Magento/FunctionalTestingFramework/Test/Util/TestNameValidationUtil.php new file mode 100644 index 000000000..d3796621e --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Test/Util/TestNameValidationUtil.php @@ -0,0 +1,60 @@ + "spaces", + "," => "commas", + "'" => "single quotes", + "\"" => "double quotes", + "{" => "curly braces", + "}" => "curly braces", + "$" => "dollar signs", + "(" => "parenthesis", + ")" => "parenthesis" + ]; + + /** + * Function which runs a validation against the blacklisted char defined in this class. Validation occurs to insure + * allure report does not error/future devOps builds do not error against illegal char. + * + * @param string $testName + * @return void + * @throws XmlException + */ + public static function validateName($testName) + { + $testChars = str_split($testName); + + $diff = array_intersect($testChars, array_keys(self::BLACKLISTED_CHAR)); + if (count($diff) > 0) { + $errorMessage = "Test name \"${testName}\" contains illegal characters, please fix and re-run."; + $uniqueDiff = array_unique(array_map(['self', 'nameMapper'], $diff)); + + foreach ($uniqueDiff as $diffChar) { + $errorMessage .= "\nTest names cannot contain " . $diffChar; + } + + throw new XmlException($errorMessage); + } + } + + /** + * Function which maps the blacklisted char to its name, function is used by the array map above. + * + * @param string $val + * @return string + */ + private static function nameMapper($val) + { + return self::BLACKLISTED_CHAR[$val]; + } +} diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php b/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php index 6e7fcb508..b15867294 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php +++ b/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php @@ -63,6 +63,9 @@ public function extractTestData($cestTestData) continue; } + // validate the test name for blacklisted char (will cause allure report issues) MQE-483 + TestNameValidationUtil::validateName($testName); + $testAnnotations = []; $testActions = $this->stripDescriptorTags( $testData, diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd index d6cd059b3..d54eb1060 100644 --- a/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd +++ b/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd @@ -22,8 +22,8 @@ - - + + @@ -55,6 +55,7 @@ + @@ -66,6 +67,11 @@ + + + + + @@ -183,6 +189,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1521,4 +1561,505 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/MetadataGenUtil.php b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/MetadataGenUtil.php similarity index 99% rename from src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/MetadataGenUtil.php rename to src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/MetadataGenUtil.php index c0de1827e..821f598a7 100644 --- a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/MetadataGenUtil.php +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/MetadataGenUtil.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\FunctionalTestingFramework\Util\MetadataGenerator; +namespace Magento\FunctionalTestingFramework\Util\MetadataGenerator\FormData; use Mustache_Engine; use Mustache_Loader_FilesystemLoader; diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/_generateMetadtataFile.php b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/_generateMetadataFile.php similarity index 85% rename from src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/_generateMetadtataFile.php rename to src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/_generateMetadataFile.php index 25aa7ee19..fce54be41 100644 --- a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/_generateMetadtataFile.php +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/_generateMetadataFile.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -require_once '../../../../../vendor/autoload.php'; +require_once '../../../../../../vendor/autoload.php'; const INPUT_TXT_FILE = 'input.yml'; @@ -12,7 +12,7 @@ $inputCfg = \Symfony\Component\Yaml\Yaml::parse(file_get_contents(INPUT_TXT_FILE)); // create new MetadataGenUtil Object -$metadataGenUtil = new Magento\FunctionalTestingFramework\Util\MetadataGenerator\MetadataGenUtil( +$metadataGenUtil = new Magento\FunctionalTestingFramework\Util\MetadataGenerator\FormData\MetadataGenUtil( $inputCfg['operationName'], $inputCfg['operationDataType'], $inputCfg['operationUrl'], diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/input.yml.sample b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/input.yml.sample similarity index 100% rename from src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/input.yml.sample rename to src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/input.yml.sample diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/operation.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/operation.mustache similarity index 83% rename from src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/operation.mustache rename to src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/operation.mustache index ad81c99ae..28321504d 100644 --- a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/operation.mustache +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/operation.mustache @@ -6,7 +6,7 @@ */ --> - + {{>object}} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/partials/field.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/partials/field.mustache similarity index 100% rename from src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/partials/field.mustache rename to src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/partials/field.mustache diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/partials/object.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/partials/object.mustache similarity index 100% rename from src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/views/partials/object.mustache rename to src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/FormData/views/partials/object.mustache diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/MetadataGenerator.php b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/MetadataGenerator.php new file mode 100644 index 000000000..64c981fe1 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/MetadataGenerator.php @@ -0,0 +1,533 @@ + 'create', + 'DELETE' => 'delete', + 'PUT' => 'update', + 'GET' => 'get', + ]; + + /** + * Build and initialize generator. + */ + public function __construct() + { + self::buildSwaggerSpec(); + $this->initMustacheTemplates(); + } + + /** + * Parse swagger spec from input json file. + * TODO: read swagger spec from magento server. + * + * @return void + */ + public function generateMetadataFromSwagger() + { + $paths = self::$swagger->getPaths(); + + foreach ($paths->getIterator() as $pathKey => $path) { + $operations = $path->getOperations(); + foreach ($operations->getIterator() as $operationKey => $operation) { + $this->renderOperation($operation, $pathKey, $operationKey); + } + } + + $definitions = self::$swagger->getDefinitions(); + foreach ($definitions->getIterator() as $defKey => $definition) { + $this->renderDefinition($defKey, $definition); + } + } + + /** + * Render swagger operations. + * + * @param Operation $operation + * @param string $path + * @param string $method + * @return void + */ + private function renderOperation($operation, $path, $method) + { + $operationArray = []; + $this->pathParams = ''; + $this->params = []; + $this->fields = []; + $operationMethod = strtoupper($method); + $operationDataType = ucfirst($operation->getOperationId()); + + $operationArray[self::TEMPLATE_VAR_OP_NAME] = self::$methodMapping[$operationMethod] . $operationDataType; + $operationArray[self::TEMPLATE_VAR_OP_DATATYPE] = $operationDataType; + $operationArray[self::TEMPLATE_VAR_OP_METHOD] = $operationMethod; + $operationArray[self::TEMPLATE_VAR_OP_AUTH] = self::AUTH; + $operationArray[self::TEMPLATE_VAR_OP_TYPE] = self::$methodMapping[$operationMethod]; + $operationArray[self::TEMPLATE_VAR_OP_URL] = $path; + + $params = $operation->getParameters(); + if (!empty($params)) { + $this->parseParams($params, $path); + $operationArray[self::TEMPLATE_VAR_OP_FIELD] = $this->fields; + $operationArray[self::TEMPLATE_VAR_OP_PARAM] = $this->params; + } + + if (!empty($this->pathParams)) { + $operationArray[self::TEMPLATE_VAR_OP_URL] .= $this->pathParams; + } + + $this->generateMetaDataFile( + self::OUTPUT_DIR, + $operationDataType, + 'operation', + $operationArray + ); + } + + /** + * Render swagger definitions. + * + * @param string $defKey + * @param ObjectSchema|ArraySchema $definition + * @return void + */ + private function renderDefinition($defKey, $definition) + { + $operationArray = []; + $this->fields = []; + + $operationArray[self::TEMPLATE_VAR_OP_NAME] = $defKey; + $operationArray[self::TEMPLATE_VAR_OP_DATATYPE] = $defKey; + $operationArray[self::TEMPLATE_VAR_OP_TYPE] = self::TEMPLATE_VAR_DEF_TYPE; + + if ($definition instanceof ObjectSchema) { + $properties = $definition->getProperties(); + if (!empty($properties)) { + $dataField = []; + $dataArray = []; + foreach ($properties->getIterator() as $propertyKey => $property) { + if ($property instanceof ArraySchema) { + $dataArray[] = $this->parseSchema($property, $propertyKey, 1, 1); + } else { + $dataField[] = $this->parseSchema($property, $propertyKey, 0, 1); + } + } + if (!empty($dataField)) { + $operationArray[self::TEMPLATE_VAR_OP_FIELD] = $dataField; + } + if (!empty($dataArray)) { + foreach ($dataArray as $array) { + $operationArray[self::TEMPLATE_VAR_OP_ARRAY.'1'][] = $array[self::TEMPLATE_VAR_OP_ARRAY.'1']; + } + } + } + } elseif ($definition instanceof ArraySchema) { + $operationArray = array_merge($operationArray, $this->parseSchema($definition, $defKey, 1, 1)); + } + + $this->generateMetaDataFile( + self::OUTPUT_DIR2, + $defKey, + 'definition', + $operationArray + ); + } + + /** + * Parse schema and return an array that will be consumed by mustache template engine. + * + * @param SchemaInterface $schema + * @param string $name + * @param bool $forArray + * @param integer $depth + * @return array + */ + private function parseSchema($schema, $name, $forArray, $depth) + { + $data = []; + + if ($schema instanceof RefSchema) { + $ref = $schema->getRef(); + preg_match(self::REF_REGEX, $ref, $matches); + if (count($matches) == 2) { + if (!$forArray) { + $data[self::TEMPLATE_VAR_FIELD_NAME] = $name; + $data[self::TEMPLATE_VAR_FIELD_TYPE] = $matches[1]; + } else { + $data[self::TEMPLATE_VAR_VALUES][] = [self::TEMPLATE_VAR_VALUE => $matches[1]]; + } + } + } elseif ($schema instanceof ArraySchema) { + $values = []; + $items = $schema->getItems(); + $data[self::TEMPLATE_VAR_OP_ARRAY.$depth][self::TEMPLATE_VAR_ARRAY_KEY] = $name; + if ($items instanceof ArrayCollection) { + foreach ($items->getIterator() as $itemKey => $item) { + $values[] = $this->parseSchema($item, $itemKey, 1, $depth+1); + } + $data[self::TEMPLATE_VAR_VALUES] = $values; + $data[self::TEMPLATE_VAR_OP_ARRAY.$depth] = $data; + } else { + $data[self::TEMPLATE_VAR_OP_ARRAY.$depth] = array_merge( + $data[self::TEMPLATE_VAR_OP_ARRAY.$depth], + $this->parseSchema($items, $name, 1, $depth+1) + ); + } + } else { + if (method_exists($schema, 'getType')) { + if (!$forArray) { + $data[self::TEMPLATE_VAR_FIELD_NAME] = $name; + $data[self::TEMPLATE_VAR_FIELD_TYPE] = $schema->getType(); + } else { + $data[self::TEMPLATE_VAR_VALUES][] = [self::TEMPLATE_VAR_VALUE => $schema->getType()]; + } + } + } + return $data; + } + + /** + * Parse params for an operation. + * + * @param ArrayCollection $params + * @param string $path + * @return void + */ + private function parseParams($params, $path) + { + foreach ($params->getIterator() as $paramKey => $param) { + if (empty($param)) { + continue; + } + + $paramIn = $param->getIn(); + if ($paramIn == 'body') { + $this->setBodyParams($param); + } elseif ($paramIn == 'path') { + $this->setPathParams($param, $path); + } elseif ($paramIn == 'query') { + $this->setQueryParams($param); + } + } + } + + /** + * Set body params for an operation. + * + * @param BodyParameter $param + * @return void + */ + private function setBodyParams($param) + { + $this->fields = []; + $required = []; + + $paramSchema = $param->getSchema(); + $paramSchemaRequired = $paramSchema->getRequired(); + if (!empty($paramSchemaRequired)) { + foreach ($paramSchemaRequired as $i => $key) { + $required[] = $key; + } + } + $paramSchemaProperties = $paramSchema->getProperties(); + foreach ($paramSchemaProperties->getIterator() as $paramPropertyKey => $paramSchemaProperty) { + $field = []; + $field[self::TEMPLATE_VAR_FIELD_NAME] = $paramPropertyKey; + $field[self::TEMPLATE_VAR_FIELD_TYPE] = $paramSchemaProperty->getType(); + if ($field[self::TEMPLATE_VAR_FIELD_TYPE] == 'ref') { + preg_match(self::REF_REGEX, $paramSchemaProperty->getRef(), $matches); + if (count($matches) == 2) { + $field[self::TEMPLATE_VAR_FIELD_TYPE] = $matches[1]; + } + } + if (in_array($paramPropertyKey, $required)) { + $field[self::TEMPLATE_VAR_FIELD_IS_REQUIRED] = 'true'; + } else { + $field[self::TEMPLATE_VAR_FIELD_IS_REQUIRED] = 'false'; + } + $this->fields[] = $field; + } + } + + /** + * Set path params for an operation. + * + * @param AbstractTypedParameter $param + * @param string $path + * @return void + */ + private function setPathParams($param, $path) + { + $pathParamStr = '{' . $param->getName() . '}'; + if (strpos($path, $pathParamStr) === false) { + $this->pathParams .= '/' . $pathParamStr; + } + } + + /** + * Set query params for an operation. + * + * @param AbstractTypedParameter $param + * @return void + */ + private function setQueryParams($param) + { + $query = []; + $query[self::TEMPLATE_VAR_PARAM_NAME] = $param->getName(); + $query[self::TEMPLATE_VAR_PARAM_TYPE] = $param->getType(); + + $this->params[] = $query; + } + + /** + * Build swagger spec from factory. + * + * @return void + */ + private static function buildSwaggerSpec() + { + $factory = new SwaggerFactory(); + self::$swagger = $factory->build(self::INPUT_TXT_FILE); + } + + /** + * Function which initializes mustache templates for file generation. + * + * @return void + */ + private function initMustacheTemplates() + { + $this->mustache_engine = new Mustache_Engine( + ['loader' => new Mustache_Loader_FilesystemLoader("views"), + 'partials_loader' => new Mustache_Loader_FilesystemLoader( + "views" . DIRECTORY_SEPARATOR . "partials" + )] + ); + } + + /** + * Render template and generate a metadata file. + * + * @param string $relativeDir + * @param string $fileName + * @param string $template + * @param array $data + * @return void + */ + private function generateMetaDataFile($relativeDir, $fileName, $template, $data) + { + $this->filepath = $relativeDir . DIRECTORY_SEPARATOR . $fileName . "-meta.xml"; + $result = $this->mustache_engine->render($template, $data); + $this->cleanAndCreateOutputDir(); + file_put_contents( + $this->filepath, + $result + ); + } + + /** + * Function which cleans any previously created fileand creates the _output dir. + * + * @return void + */ + private function cleanAndCreateOutputDir() + { + if (!file_exists(self::OUTPUT_DIR)) { + mkdir(self::OUTPUT_DIR); + } + + if (!file_exists(self::OUTPUT_DIR2)) { + mkdir(self::OUTPUT_DIR2); + } + + if (file_exists($this->filepath)) { + unlink($this->filepath); + } + } + /* + private static function debugData() { + $paramsExample = ['params' => + [ + 'paramName' => 'name', + 'paramType' => 'type' + ], + [ + 'paramName' => 'name', + 'paramType' => 'type' + ], + [ + 'paramName' => 'name', + 'paramType' => 'type' + ], + ]; + $fieldsExample = ['fields' => + [ + 'fieldName' => 'name', + 'fieldType' => 'type', + 'isRequired' => true, + ], + [ + 'fieldName' => 'name', + 'fieldType' => 'type', + 'isRequired' => true, + ], + [ + 'fieldName' => 'name', + 'fieldType' => 'type', + 'isRequired' => true, + ], + ]; + $arraysExample = ['arrays1' => + [ + 'arrayKey' => 'someKey', + 'values' => [ + 'type1', + 'type2', + ], + 'arrays2' => [ + 'arrayKey' => 'otherKey', + 'values' => [ + 'type3', + 'type4', + ], + 'arrays3' => [ + 'arrayKey' => 'anotherKey', + 'values' => [ + 'type5', + 'type6', + ], + ], + ], + ], + [ + 'arrayKey' => 'someKey', + 'values' => [ + [ + 'value' => 'type1', + ], + [ + 'value' => 'type2', + ], + ], + 'arrays2' => [ + 'arrayKey' => 'otherKey', + 'values' => [ + [ + 'value' => 'type3', + ], + [ + 'value' => 'type4', + ], + ], + 'arrays3' => [ + 'arrayKey' => 'anotherKey', + 'values' => [ + [ + 'value' => 'type5', + ], + [ + 'value' => 'type6', + ], + ], + ], + ], + ], + ]; + } + */ +} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/_generateMetadataFile.php b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/_generateMetadataFile.php new file mode 100644 index 000000000..c759b045e --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/_generateMetadataFile.php @@ -0,0 +1,10 @@ +generateMetadataFromSwagger(); diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/autoload.php b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/autoload.php new file mode 100644 index 000000000..e7108d0f4 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/autoload.php @@ -0,0 +1,17 @@ + value pairs for select)","items":{"$ref":"#/definitions/customer-data-option-interface"}},"frontend_class":{"type":"string","description":"Class which is used to display the attribute on frontend."},"user_defined":{"type":"boolean","description":"Current attribute has been defined by a user."},"sort_order":{"type":"integer","description":"Attributes sort order."},"frontend_label":{"type":"string","description":"Label which supposed to be displayed on frontend."},"note":{"type":"string","description":"The note attribute for the element."},"system":{"type":"boolean","description":"This is a system attribute."},"backend_type":{"type":"string","description":"Backend type."},"is_used_in_grid":{"type":"boolean","description":"It is used in customer grid"},"is_visible_in_grid":{"type":"boolean","description":"It is visible in customer grid"},"is_filterable_in_grid":{"type":"boolean","description":"It is filterable in customer grid"},"is_searchable_in_grid":{"type":"boolean","description":"It is searchable in customer grid"},"attribute_code":{"type":"string","description":"Code of the attribute."}},"required":["frontend_input","input_filter","store_label","validation_rules","multiline_count","visible","required","data_model","options","frontend_class","user_defined","sort_order","frontend_label","note","system","backend_type","attribute_code"]},"customer-data-validation-rule-interface":{"type":"object","description":"Validation rule interface.","properties":{"name":{"type":"string","description":"Validation rule name"},"value":{"type":"string","description":"Validation rule value"}},"required":["name","value"]},"customer-data-option-interface":{"type":"object","description":"Option interface.","properties":{"label":{"type":"string","description":"Option label"},"value":{"type":"string","description":"Option value"},"options":{"type":"array","description":"Nested options","items":{"$ref":"#/definitions/customer-data-option-interface"}}},"required":["label"]},"customer-data-customer-interface":{"type":"object","description":"Customer interface.","properties":{"id":{"type":"integer","description":"Customer id"},"group_id":{"type":"integer","description":"Group id"},"default_billing":{"type":"string","description":"Default billing address id"},"default_shipping":{"type":"string","description":"Default shipping address id"},"confirmation":{"type":"string","description":"Confirmation"},"created_at":{"type":"string","description":"Created at time"},"updated_at":{"type":"string","description":"Updated at time"},"created_in":{"type":"string","description":"Created in area"},"dob":{"type":"string","description":"Date of birth"},"email":{"type":"string","description":"Email address"},"firstname":{"type":"string","description":"First name"},"lastname":{"type":"string","description":"Last name"},"middlename":{"type":"string","description":"Middle name"},"prefix":{"type":"string","description":"Prefix"},"suffix":{"type":"string","description":"Suffix"},"gender":{"type":"integer","description":"Gender"},"store_id":{"type":"integer","description":"Store id"},"taxvat":{"type":"string","description":"Tax Vat"},"website_id":{"type":"integer","description":"Website id"},"addresses":{"type":"array","description":"Customer addresses.","items":{"$ref":"#/definitions/customer-data-address-interface"}},"disable_auto_group_change":{"type":"integer","description":"Disable auto group change flag."},"extension_attributes":{"$ref":"#/definitions/customer-data-customer-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["email","firstname","lastname"]},"customer-data-address-interface":{"type":"object","description":"Customer address interface.","properties":{"id":{"type":"integer","description":"ID"},"customer_id":{"type":"integer","description":"Customer ID"},"region":{"$ref":"#/definitions/customer-data-region-interface"},"region_id":{"type":"integer","description":"Region ID"},"country_id":{"type":"string","description":"Country code in ISO_3166-2 format"},"street":{"type":"array","description":"Street","items":{"type":"string"}},"company":{"type":"string","description":"Company"},"telephone":{"type":"string","description":"Telephone number"},"fax":{"type":"string","description":"Fax number"},"postcode":{"type":"string","description":"Postcode"},"city":{"type":"string","description":"City name"},"firstname":{"type":"string","description":"First name"},"lastname":{"type":"string","description":"Last name"},"middlename":{"type":"string","description":"Middle name"},"prefix":{"type":"string","description":"Prefix"},"suffix":{"type":"string","description":"Suffix"},"vat_id":{"type":"string","description":"Vat id"},"default_shipping":{"type":"boolean","description":"If this address is default shipping address."},"default_billing":{"type":"boolean","description":"If this address is default billing address"},"extension_attributes":{"$ref":"#/definitions/customer-data-address-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}}},"customer-data-region-interface":{"type":"object","description":"Customer address region interface.","properties":{"region_code":{"type":"string","description":"Region code"},"region":{"type":"string","description":"Region"},"region_id":{"type":"integer","description":"Region id"},"extension_attributes":{"$ref":"#/definitions/customer-data-region-extension-interface"}},"required":["region_code","region","region_id"]},"customer-data-region-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Customer\\Api\\Data\\RegionInterface"},"customer-data-address-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Customer\\Api\\Data\\AddressInterface"},"framework-attribute-interface":{"type":"object","description":"Interface for custom attribute value.","properties":{"attribute_code":{"type":"string","description":"Attribute code"},"value":{"type":"string","description":"Attribute value"}},"required":["attribute_code","value"]},"customer-data-customer-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Customer\\Api\\Data\\CustomerInterface","properties":{"is_subscribed":{"type":"boolean"},"extension_attribute":{"$ref":"#/definitions/test-module-default-hydrator-data-extension-attribute-interface"}}},"test-module-default-hydrator-data-extension-attribute-interface":{"type":"object","description":"","properties":{"id":{"type":"integer","description":"ID"},"customer_id":{"type":"integer","description":"Customer ID"},"value":{"type":"string","description":"Value"}}},"customer-data-customer-search-results-interface":{"type":"object","description":"Interface for customer search results.","properties":{"items":{"type":"array","description":"Customers list.","items":{"$ref":"#/definitions/customer-data-customer-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"customer-data-validation-results-interface":{"type":"object","description":"Validation results interface.","properties":{"valid":{"type":"boolean","description":"If the provided data is valid."},"messages":{"type":"array","description":"Error messages as array in case of validation failure, else return empty array.","items":{"type":"string"}}},"required":["valid","messages"]},"cms-data-page-interface":{"type":"object","description":"CMS page interface.","properties":{"id":{"type":"integer","description":"ID"},"identifier":{"type":"string","description":"Identifier"},"title":{"type":"string","description":"Title"},"page_layout":{"type":"string","description":"Page layout"},"meta_title":{"type":"string","description":"Meta title"},"meta_keywords":{"type":"string","description":"Meta keywords"},"meta_description":{"type":"string","description":"Meta description"},"content_heading":{"type":"string","description":"Content heading"},"content":{"type":"string","description":"Content"},"creation_time":{"type":"string","description":"Creation time"},"update_time":{"type":"string","description":"Update time"},"sort_order":{"type":"string","description":"Sort order"},"layout_update_xml":{"type":"string","description":"Layout update xml"},"custom_theme":{"type":"string","description":"Custom theme"},"custom_root_template":{"type":"string","description":"Custom root template"},"custom_layout_update_xml":{"type":"string","description":"Custom layout update xml"},"custom_theme_from":{"type":"string","description":"Custom theme from"},"custom_theme_to":{"type":"string","description":"Custom theme to"},"active":{"type":"boolean","description":"Active"}},"required":["identifier"]},"cms-data-page-search-results-interface":{"type":"object","description":"Interface for cms page search results.","properties":{"items":{"type":"array","description":"Pages list.","items":{"$ref":"#/definitions/cms-data-page-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"cms-data-block-interface":{"type":"object","description":"CMS block interface.","properties":{"id":{"type":"integer","description":"ID"},"identifier":{"type":"string","description":"Identifier"},"title":{"type":"string","description":"Title"},"content":{"type":"string","description":"Content"},"creation_time":{"type":"string","description":"Creation time"},"update_time":{"type":"string","description":"Update time"},"active":{"type":"boolean","description":"Active"}},"required":["identifier"]},"cms-data-block-search-results-interface":{"type":"object","description":"Interface for cms block search results.","properties":{"items":{"type":"array","description":"Blocks list.","items":{"$ref":"#/definitions/cms-data-block-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"catalog-data-product-interface":{"type":"object","description":"","properties":{"id":{"type":"integer","description":"Id"},"sku":{"type":"string","description":"Sku"},"name":{"type":"string","description":"Name"},"attribute_set_id":{"type":"integer","description":"Attribute set id"},"price":{"type":"number","description":"Price"},"status":{"type":"integer","description":"Status"},"visibility":{"type":"integer","description":"Visibility"},"type_id":{"type":"string","description":"Type id"},"created_at":{"type":"string","description":"Created date"},"updated_at":{"type":"string","description":"Updated date"},"weight":{"type":"number","description":"Weight"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-extension-interface"},"product_links":{"type":"array","description":"Product links info","items":{"$ref":"#/definitions/catalog-data-product-link-interface"}},"options":{"type":"array","description":"List of product options","items":{"$ref":"#/definitions/catalog-data-product-custom-option-interface"}},"media_gallery_entries":{"type":"array","description":"Media gallery entries","items":{"$ref":"#/definitions/catalog-data-product-attribute-media-gallery-entry-interface"}},"tier_prices":{"type":"array","description":"List of product tier prices","items":{"$ref":"#/definitions/catalog-data-product-tier-price-interface"}},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["sku"]},"catalog-data-product-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductInterface","properties":{"website_ids":{"type":"array","items":{"type":"integer"}},"category_links":{"type":"array","items":{"$ref":"#/definitions/catalog-data-category-link-interface"}},"stock_item":{"$ref":"#/definitions/catalog-inventory-data-stock-item-interface"},"bundle_product_options":{"type":"array","items":{"$ref":"#/definitions/bundle-data-option-interface"}},"downloadable_product_links":{"type":"array","items":{"$ref":"#/definitions/downloadable-data-link-interface"}},"downloadable_product_samples":{"type":"array","items":{"$ref":"#/definitions/downloadable-data-sample-interface"}},"giftcard_amounts":{"type":"array","items":{"$ref":"#/definitions/gift-card-data-giftcard-amount-interface"}},"configurable_product_options":{"type":"array","items":{"$ref":"#/definitions/configurable-product-data-option-interface"}},"configurable_product_links":{"type":"array","items":{"type":"integer"}}}},"catalog-data-category-link-interface":{"type":"object","description":"","properties":{"position":{"type":"integer"},"category_id":{"type":"string","description":"Category id"},"extension_attributes":{"$ref":"#/definitions/catalog-data-category-link-extension-interface"}},"required":["category_id"]},"catalog-data-category-link-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\CategoryLinkInterface"},"catalog-inventory-data-stock-item-interface":{"type":"object","description":"Interface StockItem","properties":{"item_id":{"type":"integer"},"product_id":{"type":"integer"},"stock_id":{"type":"integer","description":"Stock identifier"},"qty":{"type":"number"},"is_in_stock":{"type":"boolean","description":"Stock Availability"},"is_qty_decimal":{"type":"boolean"},"show_default_notification_message":{"type":"boolean"},"use_config_min_qty":{"type":"boolean"},"min_qty":{"type":"number","description":"Minimal quantity available for item status in stock"},"use_config_min_sale_qty":{"type":"integer"},"min_sale_qty":{"type":"number","description":"Minimum Qty Allowed in Shopping Cart or NULL when there is no limitation"},"use_config_max_sale_qty":{"type":"boolean"},"max_sale_qty":{"type":"number","description":"Maximum Qty Allowed in Shopping Cart data wrapper"},"use_config_backorders":{"type":"boolean"},"backorders":{"type":"integer","description":"Backorders status"},"use_config_notify_stock_qty":{"type":"boolean"},"notify_stock_qty":{"type":"number","description":"Notify for Quantity Below data wrapper"},"use_config_qty_increments":{"type":"boolean"},"qty_increments":{"type":"number","description":"Quantity Increments data wrapper"},"use_config_enable_qty_inc":{"type":"boolean"},"enable_qty_increments":{"type":"boolean","description":"Whether Quantity Increments is enabled"},"use_config_manage_stock":{"type":"boolean"},"manage_stock":{"type":"boolean","description":"Can Manage Stock"},"low_stock_date":{"type":"string"},"is_decimal_divided":{"type":"boolean"},"stock_status_changed_auto":{"type":"integer"},"extension_attributes":{"$ref":"#/definitions/catalog-inventory-data-stock-item-extension-interface"}},"required":["qty","is_in_stock","is_qty_decimal","show_default_notification_message","use_config_min_qty","min_qty","use_config_min_sale_qty","min_sale_qty","use_config_max_sale_qty","max_sale_qty","use_config_backorders","backorders","use_config_notify_stock_qty","notify_stock_qty","use_config_qty_increments","qty_increments","use_config_enable_qty_inc","enable_qty_increments","use_config_manage_stock","manage_stock","low_stock_date","is_decimal_divided","stock_status_changed_auto"]},"catalog-inventory-data-stock-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\CatalogInventory\\Api\\Data\\StockItemInterface"},"bundle-data-option-interface":{"type":"object","description":"Interface OptionInterface","properties":{"option_id":{"type":"integer","description":"Option id"},"title":{"type":"string","description":"Option title"},"required":{"type":"boolean","description":"Is required option"},"type":{"type":"string","description":"Input type"},"position":{"type":"integer","description":"Option position"},"sku":{"type":"string","description":"Product sku"},"product_links":{"type":"array","description":"Product links","items":{"$ref":"#/definitions/bundle-data-link-interface"}},"extension_attributes":{"$ref":"#/definitions/bundle-data-option-extension-interface"}}},"bundle-data-link-interface":{"type":"object","description":"Interface LinkInterface","properties":{"id":{"type":"string","description":"The identifier"},"sku":{"type":"string","description":"Linked product sku"},"option_id":{"type":"integer","description":"Option id"},"qty":{"type":"number","description":"Qty"},"position":{"type":"integer","description":"Position"},"is_default":{"type":"boolean","description":"Is default"},"price":{"type":"number","description":"Price"},"price_type":{"type":"integer","description":"Price type"},"can_change_quantity":{"type":"integer","description":"Whether quantity could be changed"},"extension_attributes":{"$ref":"#/definitions/bundle-data-link-extension-interface"}},"required":["is_default","price","price_type"]},"bundle-data-link-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Bundle\\Api\\Data\\LinkInterface"},"bundle-data-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Bundle\\Api\\Data\\OptionInterface"},"downloadable-data-link-interface":{"type":"object","description":"","properties":{"id":{"type":"integer","description":"Sample(or link) id"},"title":{"type":"string"},"sort_order":{"type":"integer"},"is_shareable":{"type":"integer","description":"Shareable status"},"price":{"type":"number","description":"Price"},"number_of_downloads":{"type":"integer","description":"Of downloads per user"},"link_type":{"type":"string"},"link_file":{"type":"string","description":"relative file path"},"link_file_content":{"$ref":"#/definitions/downloadable-data-file-content-interface"},"link_url":{"type":"string","description":"Link url or null when type is 'file'"},"sample_type":{"type":"string"},"sample_file":{"type":"string","description":"relative file path"},"sample_file_content":{"$ref":"#/definitions/downloadable-data-file-content-interface"},"sample_url":{"type":"string","description":"file URL"},"extension_attributes":{"$ref":"#/definitions/downloadable-data-link-extension-interface"}},"required":["sort_order","is_shareable","price","link_type","sample_type"]},"downloadable-data-file-content-interface":{"type":"object","description":"","properties":{"file_data":{"type":"string","description":"Data (base64 encoded content)"},"name":{"type":"string","description":"File name"},"extension_attributes":{"$ref":"#/definitions/downloadable-data-file-content-extension-interface"}},"required":["file_data","name"]},"downloadable-data-file-content-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Downloadable\\Api\\Data\\File\\ContentInterface"},"downloadable-data-link-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Downloadable\\Api\\Data\\LinkInterface"},"downloadable-data-sample-interface":{"type":"object","description":"","properties":{"id":{"type":"integer","description":"Sample(or link) id"},"title":{"type":"string","description":"Title"},"sort_order":{"type":"integer","description":"Order index for sample"},"sample_type":{"type":"string"},"sample_file":{"type":"string","description":"relative file path"},"sample_file_content":{"$ref":"#/definitions/downloadable-data-file-content-interface"},"sample_url":{"type":"string","description":"file URL"},"extension_attributes":{"$ref":"#/definitions/downloadable-data-sample-extension-interface"}},"required":["title","sort_order","sample_type"]},"downloadable-data-sample-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Downloadable\\Api\\Data\\SampleInterface"},"gift-card-data-giftcard-amount-interface":{"type":"object","description":"Interface GiftcardAmountInterface: this interface is used to serialize and deserialize EAV attribute giftcard_amounts","properties":{"attribute_id":{"type":"integer"},"website_id":{"type":"integer"},"value":{"type":"number"},"website_value":{"type":"number"},"extension_attributes":{"$ref":"#/definitions/gift-card-data-giftcard-amount-extension-interface"}},"required":["attribute_id","website_id","value","website_value"]},"gift-card-data-giftcard-amount-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\GiftCard\\Api\\Data\\GiftcardAmountInterface"},"configurable-product-data-option-interface":{"type":"object","description":"Interface OptionInterface","properties":{"id":{"type":"integer"},"attribute_id":{"type":"string"},"label":{"type":"string"},"position":{"type":"integer"},"is_use_default":{"type":"boolean"},"values":{"type":"array","items":{"$ref":"#/definitions/configurable-product-data-option-value-interface"}},"extension_attributes":{"$ref":"#/definitions/configurable-product-data-option-extension-interface"},"product_id":{"type":"integer"}}},"configurable-product-data-option-value-interface":{"type":"object","description":"Interface OptionValueInterface","properties":{"value_index":{"type":"integer"},"extension_attributes":{"$ref":"#/definitions/configurable-product-data-option-value-extension-interface"}},"required":["value_index"]},"configurable-product-data-option-value-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\ConfigurableProduct\\Api\\Data\\OptionValueInterface"},"configurable-product-data-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\ConfigurableProduct\\Api\\Data\\OptionInterface"},"catalog-data-product-link-interface":{"type":"object","description":"","properties":{"sku":{"type":"string","description":"SKU"},"link_type":{"type":"string","description":"Link type"},"linked_product_sku":{"type":"string","description":"Linked product sku"},"linked_product_type":{"type":"string","description":"Linked product type (simple, virtual, etc)"},"position":{"type":"integer","description":"Linked item position"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-link-extension-interface"}},"required":["sku","link_type","linked_product_sku","linked_product_type","position"]},"catalog-data-product-link-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductLinkInterface","properties":{"qty":{"type":"number"}}},"catalog-data-product-custom-option-interface":{"type":"object","description":"","properties":{"product_sku":{"type":"string","description":"Product SKU"},"option_id":{"type":"integer","description":"Option id"},"title":{"type":"string","description":"Option title"},"type":{"type":"string","description":"Option type"},"sort_order":{"type":"integer","description":"Sort order"},"is_require":{"type":"boolean","description":"Is require"},"price":{"type":"number","description":"Price"},"price_type":{"type":"string","description":"Price type"},"sku":{"type":"string","description":"Sku"},"file_extension":{"type":"string"},"max_characters":{"type":"integer"},"image_size_x":{"type":"integer"},"image_size_y":{"type":"integer"},"values":{"type":"array","items":{"$ref":"#/definitions/catalog-data-product-custom-option-values-interface"}},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-custom-option-extension-interface"}},"required":["product_sku","title","type","sort_order","is_require"]},"catalog-data-product-custom-option-values-interface":{"type":"object","description":"","properties":{"title":{"type":"string","description":"Option title"},"sort_order":{"type":"integer","description":"Sort order"},"price":{"type":"number","description":"Price"},"price_type":{"type":"string","description":"Price type"},"sku":{"type":"string","description":"Sku"},"option_type_id":{"type":"integer","description":"Option type id"}},"required":["title","sort_order","price","price_type"]},"catalog-data-product-custom-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductCustomOptionInterface"},"catalog-data-product-attribute-media-gallery-entry-interface":{"type":"object","description":"","properties":{"id":{"type":"integer","description":"Gallery entry ID"},"media_type":{"type":"string","description":"Media type"},"label":{"type":"string","description":"Gallery entry alternative text"},"position":{"type":"integer","description":"Gallery entry position (sort order)"},"disabled":{"type":"boolean","description":"If gallery entry is hidden from product page"},"types":{"type":"array","description":"Gallery entry image types (thumbnail, image, small_image etc)","items":{"type":"string"}},"file":{"type":"string","description":"File path"},"content":{"$ref":"#/definitions/framework-data-image-content-interface"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-attribute-media-gallery-entry-extension-interface"}},"required":["media_type","label","position","disabled","types"]},"framework-data-image-content-interface":{"type":"object","description":"Image Content data interface","properties":{"base64_encoded_data":{"type":"string","description":"Media data (base64 encoded content)"},"type":{"type":"string","description":"MIME type"},"name":{"type":"string","description":"Image name"}},"required":["base64_encoded_data","type","name"]},"catalog-data-product-attribute-media-gallery-entry-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductAttributeMediaGalleryEntryInterface","properties":{"video_content":{"$ref":"#/definitions/framework-data-video-content-interface"}}},"framework-data-video-content-interface":{"type":"object","description":"Video Content data interface","properties":{"media_type":{"type":"string","description":"MIME type"},"video_provider":{"type":"string","description":"Provider"},"video_url":{"type":"string","description":"Video URL"},"video_title":{"type":"string","description":"Title"},"video_description":{"type":"string","description":"Video Description"},"video_metadata":{"type":"string","description":"Metadata"}},"required":["media_type","video_provider","video_url","video_title","video_description","video_metadata"]},"catalog-data-product-tier-price-interface":{"type":"object","description":"","properties":{"customer_group_id":{"type":"integer","description":"Customer group id"},"qty":{"type":"number","description":"Tier qty"},"value":{"type":"number","description":"Price value"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-tier-price-extension-interface"}},"required":["customer_group_id","qty","value"]},"catalog-data-product-tier-price-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductTierPriceInterface","properties":{"percentage_value":{"type":"number"},"website_id":{"type":"integer"}}},"catalog-data-product-search-results-interface":{"type":"object","description":"","properties":{"items":{"type":"array","description":"Attributes list.","items":{"$ref":"#/definitions/catalog-data-product-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"catalog-data-product-attribute-type-interface":{"type":"object","description":"","properties":{"value":{"type":"string","description":"Value"},"label":{"type":"string","description":"Type label"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-attribute-type-extension-interface"}},"required":["value","label"]},"catalog-data-product-attribute-type-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductAttributeTypeInterface"},"catalog-data-product-attribute-interface":{"type":"object","description":"","properties":{"is_wysiwyg_enabled":{"type":"boolean","description":"WYSIWYG flag"},"is_html_allowed_on_front":{"type":"boolean","description":"The HTML tags are allowed on the frontend"},"used_for_sort_by":{"type":"boolean","description":"It is used for sorting in product listing"},"is_filterable":{"type":"boolean","description":"It used in layered navigation"},"is_filterable_in_search":{"type":"boolean","description":"It is used in search results layered navigation"},"is_used_in_grid":{"type":"boolean","description":"It is used in catalog product grid"},"is_visible_in_grid":{"type":"boolean","description":"It is visible in catalog product grid"},"is_filterable_in_grid":{"type":"boolean","description":"It is filterable in catalog product grid"},"position":{"type":"integer","description":"Position"},"apply_to":{"type":"array","description":"Apply to value for the element","items":{"type":"string"}},"is_searchable":{"type":"string","description":"The attribute can be used in Quick Search"},"is_visible_in_advanced_search":{"type":"string","description":"The attribute can be used in Advanced Search"},"is_comparable":{"type":"string","description":"The attribute can be compared on the frontend"},"is_used_for_promo_rules":{"type":"string","description":"The attribute can be used for promo rules"},"is_visible_on_front":{"type":"string","description":"The attribute is visible on the frontend"},"used_in_product_listing":{"type":"string","description":"The attribute can be used in product listing"},"is_visible":{"type":"boolean","description":"Attribute is visible on frontend."},"scope":{"type":"string","description":"Attribute scope"},"extension_attributes":{"$ref":"#/definitions/catalog-data-eav-attribute-extension-interface"},"attribute_id":{"type":"integer","description":"Id of the attribute."},"attribute_code":{"type":"string","description":"Code of the attribute."},"frontend_input":{"type":"string","description":"HTML for input element."},"entity_type_id":{"type":"string","description":"Entity type id"},"is_required":{"type":"boolean","description":"Attribute is required."},"options":{"type":"array","description":"Options of the attribute (key => value pairs for select)","items":{"$ref":"#/definitions/eav-data-attribute-option-interface"}},"is_user_defined":{"type":"boolean","description":"Current attribute has been defined by a user."},"default_frontend_label":{"type":"string","description":"Frontend label for default store"},"frontend_labels":{"type":"array","description":"Frontend label for each store","items":{"$ref":"#/definitions/eav-data-attribute-frontend-label-interface"}},"note":{"type":"string","description":"The note attribute for the element."},"backend_type":{"type":"string","description":"Backend type."},"backend_model":{"type":"string","description":"Backend model"},"source_model":{"type":"string","description":"Source model"},"default_value":{"type":"string","description":"Default value for the element."},"is_unique":{"type":"string","description":"This is a unique attribute"},"frontend_class":{"type":"string","description":"Frontend class of attribute"},"validation_rules":{"type":"array","description":"Validation rules.","items":{"$ref":"#/definitions/eav-data-attribute-validation-rule-interface"}},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["attribute_code","frontend_input","entity_type_id","is_required","frontend_labels"]},"catalog-data-eav-attribute-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\EavAttributeInterface"},"eav-data-attribute-option-interface":{"type":"object","description":"Created from:","properties":{"label":{"type":"string","description":"Option label"},"value":{"type":"string","description":"Option value"},"sort_order":{"type":"integer","description":"Option order"},"is_default":{"type":"boolean","description":"Default"},"store_labels":{"type":"array","description":"Option label for store scopes","items":{"$ref":"#/definitions/eav-data-attribute-option-label-interface"}}},"required":["label","value"]},"eav-data-attribute-option-label-interface":{"type":"object","description":"Interface AttributeOptionLabelInterface","properties":{"store_id":{"type":"integer","description":"Store id"},"label":{"type":"string","description":"Option label"}}},"eav-data-attribute-frontend-label-interface":{"type":"object","description":"Interface AttributeFrontendLabelInterface","properties":{"store_id":{"type":"integer","description":"Store id"},"label":{"type":"string","description":"Option label"}}},"eav-data-attribute-validation-rule-interface":{"type":"object","description":"Interface AttributeValidationRuleInterface","properties":{"key":{"type":"string","description":"Object key"},"value":{"type":"string","description":"Object value"}},"required":["key","value"]},"catalog-data-product-attribute-search-results-interface":{"type":"object","description":"","properties":{"items":{"type":"array","description":"Attributes list.","items":{"$ref":"#/definitions/catalog-data-product-attribute-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"catalog-data-category-attribute-interface":{"type":"object","description":"","properties":{"is_wysiwyg_enabled":{"type":"boolean","description":"WYSIWYG flag"},"is_html_allowed_on_front":{"type":"boolean","description":"The HTML tags are allowed on the frontend"},"used_for_sort_by":{"type":"boolean","description":"It is used for sorting in product listing"},"is_filterable":{"type":"boolean","description":"It used in layered navigation"},"is_filterable_in_search":{"type":"boolean","description":"It is used in search results layered navigation"},"is_used_in_grid":{"type":"boolean","description":"It is used in catalog product grid"},"is_visible_in_grid":{"type":"boolean","description":"It is visible in catalog product grid"},"is_filterable_in_grid":{"type":"boolean","description":"It is filterable in catalog product grid"},"position":{"type":"integer","description":"Position"},"apply_to":{"type":"array","description":"Apply to value for the element","items":{"type":"string"}},"is_searchable":{"type":"string","description":"The attribute can be used in Quick Search"},"is_visible_in_advanced_search":{"type":"string","description":"The attribute can be used in Advanced Search"},"is_comparable":{"type":"string","description":"The attribute can be compared on the frontend"},"is_used_for_promo_rules":{"type":"string","description":"The attribute can be used for promo rules"},"is_visible_on_front":{"type":"string","description":"The attribute is visible on the frontend"},"used_in_product_listing":{"type":"string","description":"The attribute can be used in product listing"},"is_visible":{"type":"boolean","description":"Attribute is visible on frontend."},"scope":{"type":"string","description":"Attribute scope"},"extension_attributes":{"$ref":"#/definitions/catalog-data-eav-attribute-extension-interface"},"attribute_id":{"type":"integer","description":"Id of the attribute."},"attribute_code":{"type":"string","description":"Code of the attribute."},"frontend_input":{"type":"string","description":"HTML for input element."},"entity_type_id":{"type":"string","description":"Entity type id"},"is_required":{"type":"boolean","description":"Attribute is required."},"options":{"type":"array","description":"Options of the attribute (key => value pairs for select)","items":{"$ref":"#/definitions/eav-data-attribute-option-interface"}},"is_user_defined":{"type":"boolean","description":"Current attribute has been defined by a user."},"default_frontend_label":{"type":"string","description":"Frontend label for default store"},"frontend_labels":{"type":"array","description":"Frontend label for each store","items":{"$ref":"#/definitions/eav-data-attribute-frontend-label-interface"}},"note":{"type":"string","description":"The note attribute for the element."},"backend_type":{"type":"string","description":"Backend type."},"backend_model":{"type":"string","description":"Backend model"},"source_model":{"type":"string","description":"Source model"},"default_value":{"type":"string","description":"Default value for the element."},"is_unique":{"type":"string","description":"This is a unique attribute"},"frontend_class":{"type":"string","description":"Frontend class of attribute"},"validation_rules":{"type":"array","description":"Validation rules.","items":{"$ref":"#/definitions/eav-data-attribute-validation-rule-interface"}},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["attribute_code","frontend_input","entity_type_id","is_required","frontend_labels"]},"catalog-data-category-attribute-search-results-interface":{"type":"object","description":"","properties":{"items":{"type":"array","description":"Attributes list.","items":{"$ref":"#/definitions/catalog-data-category-attribute-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"catalog-data-product-type-interface":{"type":"object","description":"Product type details","properties":{"name":{"type":"string","description":"Product type code"},"label":{"type":"string","description":"Product type label"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-type-extension-interface"}},"required":["name","label"]},"catalog-data-product-type-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductTypeInterface"},"eav-data-attribute-group-search-results-interface":{"type":"object","description":"Interface AttributeGroupSearchResultsInterface","properties":{"items":{"type":"array","description":"Attribute sets list.","items":{"$ref":"#/definitions/eav-data-attribute-group-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"eav-data-attribute-group-interface":{"type":"object","description":"Interface AttributeGroupInterface","properties":{"attribute_group_id":{"type":"string","description":"Id"},"attribute_group_name":{"type":"string","description":"Name"},"attribute_set_id":{"type":"integer","description":"Attribute set id"},"extension_attributes":{"$ref":"#/definitions/eav-data-attribute-group-extension-interface"}}},"eav-data-attribute-group-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Eav\\Api\\Data\\AttributeGroupInterface","properties":{"attribute_group_code":{"type":"string"},"sort_order":{"type":"string"}}},"catalog-data-tier-price-interface":{"type":"object","description":"Tier price interface.","properties":{"price":{"type":"number","description":"Tier price."},"price_type":{"type":"string","description":"Tier price type."},"website_id":{"type":"integer","description":"Website id."},"sku":{"type":"string","description":"SKU."},"customer_group":{"type":"string","description":"Customer group."},"quantity":{"type":"number","description":"Quantity."},"extension_attributes":{"$ref":"#/definitions/catalog-data-tier-price-extension-interface"}},"required":["price","price_type","website_id","sku","customer_group","quantity"]},"catalog-data-tier-price-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\TierPriceInterface"},"catalog-data-price-update-result-interface":{"type":"object","description":"Interface returned in case of incorrect price passed to efficient price API.","properties":{"message":{"type":"string","description":"Error message, that contains description of error occurred during price update."},"parameters":{"type":"array","description":"Parameters, that could be displayed in error message placeholders.","items":{"type":"string"}},"extension_attributes":{"$ref":"#/definitions/catalog-data-price-update-result-extension-interface"}},"required":["message","parameters"]},"catalog-data-price-update-result-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\PriceUpdateResultInterface"},"catalog-data-base-price-interface":{"type":"object","description":"Price interface.","properties":{"price":{"type":"number","description":"Price."},"store_id":{"type":"integer","description":"Store id."},"sku":{"type":"string","description":"SKU."},"extension_attributes":{"$ref":"#/definitions/catalog-data-base-price-extension-interface"}},"required":["price","store_id","sku"]},"catalog-data-base-price-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\BasePriceInterface"},"catalog-data-cost-interface":{"type":"object","description":"Cost interface.","properties":{"cost":{"type":"number","description":"Cost value."},"store_id":{"type":"integer","description":"Store id."},"sku":{"type":"string","description":"SKU."},"extension_attributes":{"$ref":"#/definitions/catalog-data-cost-extension-interface"}},"required":["cost","store_id","sku"]},"catalog-data-cost-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\CostInterface"},"catalog-data-special-price-interface":{"type":"object","description":"Product Special Price Interface is used to encapsulate data that can be processed by efficient price API.","properties":{"price":{"type":"number","description":"Product special price value."},"store_id":{"type":"integer","description":"ID of store, that contains special price value."},"sku":{"type":"string","description":"SKU of product, that contains special price value."},"price_from":{"type":"string","description":"Start date for special price in Y-m-d H:i:s format."},"price_to":{"type":"string","description":"End date for special price in Y-m-d H:i:s format."},"extension_attributes":{"$ref":"#/definitions/catalog-data-special-price-extension-interface"}},"required":["price","store_id","sku","price_from","price_to"]},"catalog-data-special-price-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\SpecialPriceInterface"},"catalog-data-category-interface":{"type":"object","description":"","properties":{"id":{"type":"integer"},"parent_id":{"type":"integer","description":"Parent category ID"},"name":{"type":"string","description":"Category name"},"is_active":{"type":"boolean","description":"Whether category is active"},"position":{"type":"integer","description":"Category position"},"level":{"type":"integer","description":"Category level"},"children":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"path":{"type":"string"},"available_sort_by":{"type":"array","items":{"type":"string"}},"include_in_menu":{"type":"boolean"},"extension_attributes":{"$ref":"#/definitions/catalog-data-category-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["name"]},"catalog-data-category-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\CategoryInterface"},"catalog-data-category-tree-interface":{"type":"object","description":"","properties":{"id":{"type":"integer"},"parent_id":{"type":"integer","description":"Parent category ID"},"name":{"type":"string","description":"Category name"},"is_active":{"type":"boolean","description":"Whether category is active"},"position":{"type":"integer","description":"Category position"},"level":{"type":"integer","description":"Category level"},"product_count":{"type":"integer","description":"Product count"},"children_data":{"type":"array","items":{"$ref":"#/definitions/catalog-data-category-tree-interface"}}},"required":["parent_id","name","is_active","position","level","product_count","children_data"]},"catalog-data-category-search-results-interface":{"type":"object","description":"","properties":{"items":{"type":"array","description":"Categories","items":{"$ref":"#/definitions/catalog-data-category-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"catalog-data-product-custom-option-type-interface":{"type":"object","description":"","properties":{"label":{"type":"string","description":"Option type label"},"code":{"type":"string","description":"Option type code"},"group":{"type":"string","description":"Option type group"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-custom-option-type-extension-interface"}},"required":["label","code","group"]},"catalog-data-product-custom-option-type-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductCustomOptionTypeInterface"},"catalog-data-product-link-type-interface":{"type":"object","description":"","properties":{"code":{"type":"integer","description":"Link type code"},"name":{"type":"string","description":"Link type name"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-link-type-extension-interface"}},"required":["code","name"]},"catalog-data-product-link-type-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductLinkTypeInterface"},"catalog-data-product-link-attribute-interface":{"type":"object","description":"","properties":{"code":{"type":"string","description":"Attribute code"},"type":{"type":"string","description":"Attribute type"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-link-attribute-extension-interface"}},"required":["code","type"]},"catalog-data-product-link-attribute-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductLinkAttributeInterface"},"catalog-data-category-product-link-interface":{"type":"object","description":"","properties":{"sku":{"type":"string"},"position":{"type":"integer"},"category_id":{"type":"string","description":"Category id"},"extension_attributes":{"$ref":"#/definitions/catalog-data-category-product-link-extension-interface"}},"required":["category_id"]},"catalog-data-category-product-link-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\CategoryProductLinkInterface"},"catalog-data-product-website-link-interface":{"type":"object","description":"","properties":{"sku":{"type":"string"},"website_id":{"type":"integer","description":"Website ids"}},"required":["sku","website_id"]},"catalog-data-product-render-search-results-interface":{"type":"object","description":"Dto that holds render information about products","properties":{"items":{"type":"array","description":"List of products rendered information","items":{"$ref":"#/definitions/catalog-data-product-render-interface"}}},"required":["items"]},"catalog-data-product-render-interface":{"type":"object","description":"Represents Data Object which holds enough information to render product This information is put into part as Add To Cart or Add to Compare Data or Price Data","properties":{"add_to_cart_button":{"$ref":"#/definitions/catalog-data-product-render-button-interface"},"add_to_compare_button":{"$ref":"#/definitions/catalog-data-product-render-button-interface"},"price_info":{"$ref":"#/definitions/catalog-data-product-render-price-info-interface"},"images":{"type":"array","description":"Enough information, that needed to render image on front","items":{"$ref":"#/definitions/catalog-data-product-render-image-interface"}},"url":{"type":"string","description":"Product url"},"id":{"type":"integer","description":"Product identifier"},"name":{"type":"string","description":"Product name"},"type":{"type":"string","description":"Product type. Such as bundle, grouped, simple, etc..."},"is_salable":{"type":"string","description":"Information about product saleability (In Stock)"},"store_id":{"type":"integer","description":"Information about current store id or requested store id"},"currency_code":{"type":"string","description":"Current or desired currency code to product"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-render-extension-interface"}},"required":["add_to_cart_button","add_to_compare_button","price_info","images","url","id","name","type","is_salable","store_id","currency_code","extension_attributes"]},"catalog-data-product-render-button-interface":{"type":"object","description":"Button interface. This interface represents all manner of product buttons: add to cart, add to compare, etc... The buttons describes by this interface should have interaction with backend","properties":{"post_data":{"type":"string","description":"Post data"},"url":{"type":"string","description":"Url, needed to add product to cart"},"required_options":{"type":"boolean","description":"Flag whether a product has options or not"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-render-button-extension-interface"}},"required":["post_data","url","required_options"]},"catalog-data-product-render-button-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductRender\\ButtonInterface"},"catalog-data-product-render-price-info-interface":{"type":"object","description":"Price interface.","properties":{"final_price":{"type":"number","description":"Final price"},"max_price":{"type":"number","description":"Max price of a product"},"max_regular_price":{"type":"number","description":"Max regular price"},"minimal_regular_price":{"type":"number","description":"Minimal regular price"},"special_price":{"type":"number","description":"Special price"},"minimal_price":{"type":"number"},"regular_price":{"type":"number","description":"Regular price"},"formatted_prices":{"$ref":"#/definitions/catalog-data-product-render-formatted-price-info-interface"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-render-price-info-extension-interface"}},"required":["final_price","max_price","max_regular_price","minimal_regular_price","special_price","minimal_price","regular_price","formatted_prices"]},"catalog-data-product-render-formatted-price-info-interface":{"type":"object","description":"Formatted Price interface. Aggregate formatted html with price representations. E.g.: $9.00 Consider currency, rounding and html","properties":{"final_price":{"type":"string","description":"Html with final price"},"max_price":{"type":"string","description":"Max price of a product"},"minimal_price":{"type":"string","description":"The minimal price of the product or variation"},"max_regular_price":{"type":"string","description":"Max regular price"},"minimal_regular_price":{"type":"string","description":"Minimal regular price"},"special_price":{"type":"string","description":"Special price"},"regular_price":{"type":"string","description":"Price - is price of product without discounts and special price with taxes and fixed product tax"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-render-formatted-price-info-extension-interface"}},"required":["final_price","max_price","minimal_price","max_regular_price","minimal_regular_price","special_price","regular_price"]},"catalog-data-product-render-formatted-price-info-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductRender\\FormattedPriceInfoInterface"},"catalog-data-product-render-price-info-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductRender\\PriceInfoInterface","properties":{"msrp":{"$ref":"#/definitions/msrp-data-product-render-msrp-price-info-interface"},"tax_adjustments":{"$ref":"#/definitions/catalog-data-product-render-price-info-interface"},"weee_attributes":{"type":"array","items":{"$ref":"#/definitions/weee-data-product-render-weee-adjustment-attribute-interface"}},"weee_adjustment":{"type":"string"}}},"msrp-data-product-render-msrp-price-info-interface":{"type":"object","description":"Price interface.","properties":{"msrp_price":{"type":"string"},"is_applicable":{"type":"string"},"is_shown_price_on_gesture":{"type":"string"},"msrp_message":{"type":"string"},"explanation_message":{"type":"string"},"extension_attributes":{"$ref":"#/definitions/msrp-data-product-render-msrp-price-info-extension-interface"}},"required":["msrp_price","is_applicable","is_shown_price_on_gesture","msrp_message","explanation_message"]},"msrp-data-product-render-msrp-price-info-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Msrp\\Api\\Data\\ProductRender\\MsrpPriceInfoInterface"},"weee-data-product-render-weee-adjustment-attribute-interface":{"type":"object","description":"List of all weee attributes, their amounts, etc.., that product has","properties":{"amount":{"type":"string","description":"Weee attribute amount"},"tax_amount":{"type":"string","description":"Tax which is calculated to fixed product tax attribute"},"tax_amount_incl_tax":{"type":"string","description":"Tax amount of weee attribute"},"amount_excl_tax":{"type":"string","description":"Product amount exclude tax"},"attribute_code":{"type":"string","description":"Weee attribute code"},"extension_attributes":{"$ref":"#/definitions/weee-data-product-render-weee-adjustment-attribute-extension-interface"}},"required":["amount","tax_amount","tax_amount_incl_tax","amount_excl_tax","attribute_code","extension_attributes"]},"weee-data-product-render-weee-adjustment-attribute-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Weee\\Api\\Data\\ProductRender\\WeeeAdjustmentAttributeInterface"},"catalog-data-product-render-image-interface":{"type":"object","description":"Product Render image interface. Represents physical characteristics of image, that can be used in product listing or product view","properties":{"url":{"type":"string","description":"Image url"},"code":{"type":"string","description":"Image code"},"height":{"type":"number","description":"Image height"},"width":{"type":"number","description":"Image width in px"},"label":{"type":"string","description":"Image label"},"resized_width":{"type":"number","description":"Resize width"},"resized_height":{"type":"number","description":"Resize height"},"extension_attributes":{"$ref":"#/definitions/catalog-data-product-render-image-extension-interface"}},"required":["url","code","height","width","label","resized_width","resized_height"]},"catalog-data-product-render-image-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductRender\\ImageInterface"},"catalog-data-product-render-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductRenderInterface","properties":{"wishlist_button":{"$ref":"#/definitions/catalog-data-product-render-button-interface"},"review_html":{"type":"string"}}},"catalog-inventory-data-stock-status-collection-interface":{"type":"object","description":"Stock Status collection interface","properties":{"items":{"type":"array","description":"Items","items":{"$ref":"#/definitions/catalog-inventory-data-stock-status-interface"}},"search_criteria":{"$ref":"#/definitions/catalog-inventory-stock-status-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"catalog-inventory-data-stock-status-interface":{"type":"object","description":"Interface StockStatusInterface","properties":{"product_id":{"type":"integer"},"stock_id":{"type":"integer"},"qty":{"type":"integer"},"stock_status":{"type":"integer"},"stock_item":{"$ref":"#/definitions/catalog-inventory-data-stock-item-interface"},"extension_attributes":{"$ref":"#/definitions/catalog-inventory-data-stock-status-extension-interface"}},"required":["product_id","stock_id","qty","stock_status","stock_item"]},"catalog-inventory-data-stock-status-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\CatalogInventory\\Api\\Data\\StockStatusInterface"},"catalog-inventory-stock-status-criteria-interface":{"type":"object","description":"Interface StockStatusCriteriaInterface","properties":{"mapper_interface_name":{"type":"string","description":"Associated Mapper Interface name"},"criteria_list":{"type":"array","description":"Criteria objects added to current Composite Criteria","items":{"$ref":"#/definitions/framework-criteria-interface"}},"filters":{"type":"array","description":"List of filters","items":{"type":"string"}},"orders":{"type":"array","description":"Ordering criteria","items":{"type":"string"}},"limit":{"type":"array","description":"Limit","items":{"type":"string"}}},"required":["mapper_interface_name","criteria_list","filters","orders","limit"]},"framework-criteria-interface":{"type":"object","description":"Interface CriteriaInterface","properties":{"mapper_interface_name":{"type":"string","description":"Associated Mapper Interface name"},"criteria_list":{"type":"array","description":"Criteria objects added to current Composite Criteria","items":{"$ref":"#/definitions/framework-criteria-interface"}},"filters":{"type":"array","description":"List of filters","items":{"type":"string"}},"orders":{"type":"array","description":"Ordering criteria","items":{"type":"string"}},"limit":{"type":"array","description":"Limit","items":{"type":"string"}}},"required":["mapper_interface_name","criteria_list","filters","orders","limit"]},"bundle-data-option-type-interface":{"type":"object","description":"Interface OptionTypeInterface","properties":{"label":{"type":"string","description":"Type label"},"code":{"type":"string","description":"Type code"},"extension_attributes":{"$ref":"#/definitions/bundle-data-option-type-extension-interface"}},"required":["label","code"]},"bundle-data-option-type-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Bundle\\Api\\Data\\OptionTypeInterface"},"quote-data-cart-interface":{"type":"object","description":"Interface CartInterface","properties":{"id":{"type":"integer","description":"Cart/quote ID."},"created_at":{"type":"string","description":"Cart creation date and time. Otherwise, null."},"updated_at":{"type":"string","description":"Cart last update date and time. Otherwise, null."},"converted_at":{"type":"string","description":"Cart conversion date and time. Otherwise, null."},"is_active":{"type":"boolean","description":"Active status flag value. Otherwise, null."},"is_virtual":{"type":"boolean","description":"Virtual flag value. Otherwise, null."},"items":{"type":"array","description":"Array of items. Otherwise, null.","items":{"$ref":"#/definitions/quote-data-cart-item-interface"}},"items_count":{"type":"integer","description":"Number of different items or products in the cart. Otherwise, null."},"items_qty":{"type":"number","description":"Total quantity of all cart items. Otherwise, null."},"customer":{"$ref":"#/definitions/customer-data-customer-interface"},"billing_address":{"$ref":"#/definitions/quote-data-address-interface"},"reserved_order_id":{"type":"integer","description":"Reserved order ID. Otherwise, null."},"orig_order_id":{"type":"integer","description":"Original order ID. Otherwise, null."},"currency":{"$ref":"#/definitions/quote-data-currency-interface"},"customer_is_guest":{"type":"boolean","description":"For guest customers, false for logged in customers"},"customer_note":{"type":"string","description":"Notice text"},"customer_note_notify":{"type":"boolean","description":"Customer notification flag"},"customer_tax_class_id":{"type":"integer","description":"Customer tax class ID."},"store_id":{"type":"integer","description":"Store identifier"},"extension_attributes":{"$ref":"#/definitions/quote-data-cart-extension-interface"}},"required":["id","customer","store_id"]},"quote-data-cart-item-interface":{"type":"object","description":"Interface CartItemInterface","properties":{"item_id":{"type":"integer","description":"Item ID. Otherwise, null."},"sku":{"type":"string","description":"Product SKU. Otherwise, null."},"qty":{"type":"number","description":"Product quantity."},"name":{"type":"string","description":"Product name. Otherwise, null."},"price":{"type":"number","description":"Product price. Otherwise, null."},"product_type":{"type":"string","description":"Product type. Otherwise, null."},"quote_id":{"type":"string","description":"Quote id."},"product_option":{"$ref":"#/definitions/quote-data-product-option-interface"},"extension_attributes":{"$ref":"#/definitions/quote-data-cart-item-extension-interface"}},"required":["qty","quote_id"]},"quote-data-product-option-interface":{"type":"object","description":"Product option interface","properties":{"extension_attributes":{"$ref":"#/definitions/quote-data-product-option-extension-interface"}}},"quote-data-product-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\ProductOptionInterface","properties":{"custom_options":{"type":"array","items":{"$ref":"#/definitions/catalog-data-custom-option-interface"}},"bundle_options":{"type":"array","items":{"$ref":"#/definitions/bundle-data-bundle-option-interface"}},"downloadable_option":{"$ref":"#/definitions/downloadable-data-downloadable-option-interface"},"giftcard_item_option":{"$ref":"#/definitions/gift-card-data-gift-card-option-interface"},"configurable_item_options":{"type":"array","items":{"$ref":"#/definitions/configurable-product-data-configurable-item-option-value-interface"}}}},"catalog-data-custom-option-interface":{"type":"object","description":"Interface CustomOptionInterface","properties":{"option_id":{"type":"string","description":"Option id"},"option_value":{"type":"string","description":"Option value"},"extension_attributes":{"$ref":"#/definitions/catalog-data-custom-option-extension-interface"}},"required":["option_id","option_value"]},"catalog-data-custom-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\CustomOptionInterface","properties":{"file_info":{"$ref":"#/definitions/framework-data-image-content-interface"}}},"bundle-data-bundle-option-interface":{"type":"object","description":"Interface BundleOptionInterface","properties":{"option_id":{"type":"integer","description":"Bundle option id."},"option_qty":{"type":"integer","description":"Bundle option quantity."},"option_selections":{"type":"array","description":"Bundle option selection ids.","items":{"type":"integer"}},"extension_attributes":{"$ref":"#/definitions/bundle-data-bundle-option-extension-interface"}},"required":["option_id","option_qty","option_selections"]},"bundle-data-bundle-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Bundle\\Api\\Data\\BundleOptionInterface"},"downloadable-data-downloadable-option-interface":{"type":"object","description":"Downloadable Option","properties":{"downloadable_links":{"type":"array","description":"The list of downloadable links","items":{"type":"integer"}}},"required":["downloadable_links"]},"gift-card-data-gift-card-option-interface":{"type":"object","description":"Interface GiftCardOptionInterface","properties":{"giftcard_amount":{"type":"string","description":"Gift card amount."},"custom_giftcard_amount":{"type":"number","description":"Gift card open amount value."},"giftcard_sender_name":{"type":"string","description":"Gift card sender name."},"giftcard_recipient_name":{"type":"string","description":"Gift card recipient name."},"giftcard_sender_email":{"type":"string","description":"Gift card sender email."},"giftcard_recipient_email":{"type":"string","description":"Gift card recipient email."},"giftcard_message":{"type":"string","description":"Giftcard message."},"extension_attributes":{"$ref":"#/definitions/gift-card-data-gift-card-option-extension-interface"}},"required":["giftcard_amount","giftcard_sender_name","giftcard_recipient_name","giftcard_sender_email","giftcard_recipient_email"]},"gift-card-data-gift-card-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\GiftCard\\Api\\Data\\GiftCardOptionInterface"},"configurable-product-data-configurable-item-option-value-interface":{"type":"object","description":"Interface ConfigurableItemOptionValueInterface","properties":{"option_id":{"type":"string","description":"Option SKU"},"option_value":{"type":"integer","description":"Item id"},"extension_attributes":{"$ref":"#/definitions/configurable-product-data-configurable-item-option-value-extension-interface"}},"required":["option_id"]},"configurable-product-data-configurable-item-option-value-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\ConfigurableProduct\\Api\\Data\\ConfigurableItemOptionValueInterface"},"quote-data-cart-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\CartItemInterface"},"quote-data-address-interface":{"type":"object","description":"Interface AddressInterface","properties":{"id":{"type":"integer","description":"Id"},"region":{"type":"string","description":"Region name"},"region_id":{"type":"integer","description":"Region id"},"region_code":{"type":"string","description":"Region code"},"country_id":{"type":"string","description":"Country id"},"street":{"type":"array","description":"Street","items":{"type":"string"}},"company":{"type":"string","description":"Company"},"telephone":{"type":"string","description":"Telephone number"},"fax":{"type":"string","description":"Fax number"},"postcode":{"type":"string","description":"Postcode"},"city":{"type":"string","description":"City name"},"firstname":{"type":"string","description":"First name"},"lastname":{"type":"string","description":"Last name"},"middlename":{"type":"string","description":"Middle name"},"prefix":{"type":"string","description":"Prefix"},"suffix":{"type":"string","description":"Suffix"},"vat_id":{"type":"string","description":"Vat id"},"customer_id":{"type":"integer","description":"Customer id"},"email":{"type":"string","description":"Billing/shipping email"},"same_as_billing":{"type":"integer","description":"Same as billing flag"},"customer_address_id":{"type":"integer","description":"Customer address id"},"save_in_address_book":{"type":"integer","description":"Save in address book flag"},"extension_attributes":{"$ref":"#/definitions/quote-data-address-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["region","region_id","region_code","country_id","street","telephone","postcode","city","firstname","lastname","email"]},"quote-data-address-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\AddressInterface","properties":{"gift_registry_id":{"type":"integer"}}},"quote-data-currency-interface":{"type":"object","description":"Interface CurrencyInterface","properties":{"global_currency_code":{"type":"string","description":"Global currency code"},"base_currency_code":{"type":"string","description":"Base currency code"},"store_currency_code":{"type":"string","description":"Store currency code"},"quote_currency_code":{"type":"string","description":"Quote currency code"},"store_to_base_rate":{"type":"number","description":"Store currency to base currency rate"},"store_to_quote_rate":{"type":"number","description":"Store currency to quote currency rate"},"base_to_global_rate":{"type":"number","description":"Base currency to global currency rate"},"base_to_quote_rate":{"type":"number","description":"Base currency to quote currency rate"},"extension_attributes":{"$ref":"#/definitions/quote-data-currency-extension-interface"}}},"quote-data-currency-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\CurrencyInterface"},"quote-data-cart-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\CartInterface","properties":{"shipping_assignments":{"type":"array","items":{"$ref":"#/definitions/quote-data-shipping-assignment-interface"}},"quote_api_test_attribute":{"$ref":"#/definitions/user-data-user-interface"}}},"quote-data-shipping-assignment-interface":{"type":"object","description":"Interface ShippingAssignmentInterface","properties":{"shipping":{"$ref":"#/definitions/quote-data-shipping-interface"},"items":{"type":"array","items":{"$ref":"#/definitions/quote-data-cart-item-interface"}},"extension_attributes":{"$ref":"#/definitions/quote-data-shipping-assignment-extension-interface"}},"required":["shipping","items"]},"quote-data-shipping-interface":{"type":"object","description":"Interface ShippingInterface","properties":{"address":{"$ref":"#/definitions/quote-data-address-interface"},"method":{"type":"string","description":"Shipping method"},"extension_attributes":{"$ref":"#/definitions/quote-data-shipping-extension-interface"}},"required":["address","method"]},"quote-data-shipping-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\ShippingInterface"},"quote-data-shipping-assignment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\ShippingAssignmentInterface"},"user-data-user-interface":{"type":"object","description":"Admin user interface.","properties":{"id":{"type":"integer","description":"ID."},"first_name":{"type":"string","description":"First name."},"last_name":{"type":"string","description":"Last name."},"email":{"type":"string","description":"Email."},"user_name":{"type":"string","description":"User name."},"password":{"type":"string","description":"Password or password hash."},"created":{"type":"string","description":"User record creation date."},"modified":{"type":"string","description":"User record modification date."},"is_active":{"type":"integer","description":"If user is active."},"interface_locale":{"type":"string","description":"User interface locale."}},"required":["id","first_name","last_name","email","user_name","password","created","modified","is_active","interface_locale"]},"quote-data-cart-search-results-interface":{"type":"object","description":"Interface CartSearchResultsInterface","properties":{"items":{"type":"array","description":"Carts list.","items":{"$ref":"#/definitions/quote-data-cart-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"quote-data-payment-interface":{"type":"object","description":"Interface PaymentInterface","properties":{"po_number":{"type":"string","description":"Purchase order number"},"method":{"type":"string","description":"Payment method code"},"additional_data":{"type":"array","description":"Payment additional details","items":{"type":"string"}},"extension_attributes":{"$ref":"#/definitions/quote-data-payment-extension-interface"}},"required":["method"]},"quote-data-payment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\PaymentInterface","properties":{"agreement_ids":{"type":"array","items":{"type":"string"}}}},"quote-data-shipping-method-interface":{"type":"object","description":"Interface ShippingMethodInterface","properties":{"carrier_code":{"type":"string","description":"Shipping carrier code."},"method_code":{"type":"string","description":"Shipping method code."},"carrier_title":{"type":"string","description":"Shipping carrier title. Otherwise, null."},"method_title":{"type":"string","description":"Shipping method title. Otherwise, null."},"amount":{"type":"number","description":"Shipping amount in store currency."},"base_amount":{"type":"number","description":"Shipping amount in base currency."},"available":{"type":"boolean","description":"The value of the availability flag for the current shipping method."},"extension_attributes":{"$ref":"#/definitions/quote-data-shipping-method-extension-interface"},"error_message":{"type":"string","description":"Shipping Error message."},"price_excl_tax":{"type":"number","description":"Shipping price excl tax."},"price_incl_tax":{"type":"number","description":"Shipping price incl tax."}},"required":["carrier_code","method_code","amount","base_amount","available","error_message","price_excl_tax","price_incl_tax"]},"quote-data-shipping-method-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\ShippingMethodInterface"},"quote-data-payment-method-interface":{"type":"object","description":"Interface PaymentMethodInterface","properties":{"code":{"type":"string","description":"Payment method code"},"title":{"type":"string","description":"Payment method title"}},"required":["code","title"]},"quote-data-totals-interface":{"type":"object","description":"Interface TotalsInterface","properties":{"grand_total":{"type":"number","description":"Grand total in quote currency"},"base_grand_total":{"type":"number","description":"Grand total in base currency"},"subtotal":{"type":"number","description":"Subtotal in quote currency"},"base_subtotal":{"type":"number","description":"Subtotal in base currency"},"discount_amount":{"type":"number","description":"Discount amount in quote currency"},"base_discount_amount":{"type":"number","description":"Discount amount in base currency"},"subtotal_with_discount":{"type":"number","description":"Subtotal in quote currency with applied discount"},"base_subtotal_with_discount":{"type":"number","description":"Subtotal in base currency with applied discount"},"shipping_amount":{"type":"number","description":"Shipping amount in quote currency"},"base_shipping_amount":{"type":"number","description":"Shipping amount in base currency"},"shipping_discount_amount":{"type":"number","description":"Shipping discount amount in quote currency"},"base_shipping_discount_amount":{"type":"number","description":"Shipping discount amount in base currency"},"tax_amount":{"type":"number","description":"Tax amount in quote currency"},"base_tax_amount":{"type":"number","description":"Tax amount in base currency"},"weee_tax_applied_amount":{"type":"number","description":"Item weee tax applied amount in quote currency."},"shipping_tax_amount":{"type":"number","description":"Shipping tax amount in quote currency"},"base_shipping_tax_amount":{"type":"number","description":"Shipping tax amount in base currency"},"subtotal_incl_tax":{"type":"number","description":"Subtotal including tax in quote currency"},"base_subtotal_incl_tax":{"type":"number","description":"Subtotal including tax in base currency"},"shipping_incl_tax":{"type":"number","description":"Shipping including tax in quote currency"},"base_shipping_incl_tax":{"type":"number","description":"Shipping including tax in base currency"},"base_currency_code":{"type":"string","description":"Base currency code"},"quote_currency_code":{"type":"string","description":"Quote currency code"},"coupon_code":{"type":"string","description":"Applied coupon code"},"items_qty":{"type":"integer","description":"Items qty"},"items":{"type":"array","description":"Totals by items","items":{"$ref":"#/definitions/quote-data-totals-item-interface"}},"total_segments":{"type":"array","description":"Dynamically calculated totals","items":{"$ref":"#/definitions/quote-data-total-segment-interface"}},"extension_attributes":{"$ref":"#/definitions/quote-data-totals-extension-interface"}},"required":["weee_tax_applied_amount","total_segments"]},"quote-data-totals-item-interface":{"type":"object","description":"Interface TotalsItemInterface","properties":{"item_id":{"type":"integer","description":"Item id"},"price":{"type":"number","description":"Item price in quote currency."},"base_price":{"type":"number","description":"Item price in base currency."},"qty":{"type":"number","description":"Item quantity."},"row_total":{"type":"number","description":"Row total in quote currency."},"base_row_total":{"type":"number","description":"Row total in base currency."},"row_total_with_discount":{"type":"number","description":"Row total with discount in quote currency. Otherwise, null."},"tax_amount":{"type":"number","description":"Tax amount in quote currency. Otherwise, null."},"base_tax_amount":{"type":"number","description":"Tax amount in base currency. Otherwise, null."},"tax_percent":{"type":"number","description":"Tax percent. Otherwise, null."},"discount_amount":{"type":"number","description":"Discount amount in quote currency. Otherwise, null."},"base_discount_amount":{"type":"number","description":"Discount amount in base currency. Otherwise, null."},"discount_percent":{"type":"number","description":"Discount percent. Otherwise, null."},"price_incl_tax":{"type":"number","description":"Price including tax in quote currency. Otherwise, null."},"base_price_incl_tax":{"type":"number","description":"Price including tax in base currency. Otherwise, null."},"row_total_incl_tax":{"type":"number","description":"Row total including tax in quote currency. Otherwise, null."},"base_row_total_incl_tax":{"type":"number","description":"Row total including tax in base currency. Otherwise, null."},"options":{"type":"string","description":"Item price in quote currency."},"weee_tax_applied_amount":{"type":"number","description":"Item weee tax applied amount in quote currency."},"weee_tax_applied":{"type":"string","description":"Item weee tax applied in quote currency."},"extension_attributes":{"$ref":"#/definitions/quote-data-totals-item-extension-interface"},"name":{"type":"string","description":"Product name. Otherwise, null."}},"required":["item_id","price","base_price","qty","row_total","base_row_total","options","weee_tax_applied_amount","weee_tax_applied"]},"quote-data-totals-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\TotalsItemInterface"},"quote-data-total-segment-interface":{"type":"object","description":"Interface TotalsInterface","properties":{"code":{"type":"string","description":"Code"},"title":{"type":"string","description":"Total title"},"value":{"type":"number","description":"Total value"},"area":{"type":"string","description":"Display area code."},"extension_attributes":{"$ref":"#/definitions/quote-data-total-segment-extension-interface"}},"required":["code","value"]},"quote-data-total-segment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\TotalSegmentInterface","properties":{"gift_cards":{"type":"string"},"tax_grandtotal_details":{"type":"array","items":{"$ref":"#/definitions/tax-data-grand-total-details-interface"}},"gw_order_id":{"type":"string"},"gw_item_ids":{"type":"array","items":{"type":"string"}},"gw_allow_gift_receipt":{"type":"string"},"gw_add_card":{"type":"string"},"gw_price":{"type":"string"},"gw_base_price":{"type":"string"},"gw_items_price":{"type":"string"},"gw_items_base_price":{"type":"string"},"gw_card_price":{"type":"string"},"gw_card_base_price":{"type":"string"},"gw_base_tax_amount":{"type":"string"},"gw_tax_amount":{"type":"string"},"gw_items_base_tax_amount":{"type":"string"},"gw_items_tax_amount":{"type":"string"},"gw_card_base_tax_amount":{"type":"string"},"gw_card_tax_amount":{"type":"string"},"gw_price_incl_tax":{"type":"string"},"gw_base_price_incl_tax":{"type":"string"},"gw_card_price_incl_tax":{"type":"string"},"gw_card_base_price_incl_tax":{"type":"string"},"gw_items_price_incl_tax":{"type":"string"},"gw_items_base_price_incl_tax":{"type":"string"}}},"tax-data-grand-total-details-interface":{"type":"object","description":"Interface GrandTotalDetailsInterface","properties":{"amount":{"type":"number","description":"Tax amount value"},"rates":{"type":"array","description":"Tax rates info","items":{"$ref":"#/definitions/tax-data-grand-total-rates-interface"}},"group_id":{"type":"integer","description":"Group identifier"}},"required":["amount","rates","group_id"]},"tax-data-grand-total-rates-interface":{"type":"object","description":"Interface GrandTotalRatesInterface","properties":{"percent":{"type":"string","description":"Tax percentage value"},"title":{"type":"string","description":"Rate title"}},"required":["percent","title"]},"quote-data-totals-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\TotalsInterface","properties":{"coupon_label":{"type":"string"},"base_customer_balance_amount":{"type":"number"},"customer_balance_amount":{"type":"number"},"reward_points_balance":{"type":"number"},"reward_currency_amount":{"type":"number"},"base_reward_currency_amount":{"type":"number"}}},"quote-data-totals-additional-data-interface":{"type":"object","description":"Additional data for totals collection.","properties":{"extension_attributes":{"$ref":"#/definitions/quote-data-totals-additional-data-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}}},"quote-data-totals-additional-data-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Quote\\Api\\Data\\TotalsAdditionalDataInterface","properties":{"gift_messages":{"type":"array","items":{"$ref":"#/definitions/gift-message-data-message-interface"}}}},"gift-message-data-message-interface":{"type":"object","description":"Interface MessageInterface","properties":{"gift_message_id":{"type":"integer","description":"Gift message ID. Otherwise, null."},"customer_id":{"type":"integer","description":"Customer ID. Otherwise, null."},"sender":{"type":"string","description":"Sender name."},"recipient":{"type":"string","description":"Recipient name."},"message":{"type":"string","description":"Message text."},"extension_attributes":{"$ref":"#/definitions/gift-message-data-message-extension-interface"}},"required":["sender","recipient","message"]},"gift-message-data-message-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\GiftMessage\\Api\\Data\\MessageInterface","properties":{"entity_id":{"type":"string"},"entity_type":{"type":"string"},"wrapping_id":{"type":"integer"},"wrapping_allow_gift_receipt":{"type":"boolean"},"wrapping_add_printed_card":{"type":"boolean"}}},"framework-search-search-result-interface":{"type":"object","description":"Interface SearchResultInterface","properties":{"items":{"type":"array","items":{"$ref":"#/definitions/framework-search-document-interface"}},"aggregations":{"$ref":"#/definitions/framework-search-aggregation-interface"},"search_criteria":{"$ref":"#/definitions/framework-search-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","aggregations","search_criteria","total_count"]},"framework-search-document-interface":{"type":"object","description":"Interface \\Magento\\Framework\\Api\\Search\\DocumentInterface","properties":{"id":{"type":"integer"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["id"]},"framework-search-aggregation-interface":{"type":"object","description":"Faceted data","properties":{"buckets":{"type":"array","description":"All Document fields","items":{"$ref":"#/definitions/framework-search-bucket-interface"}},"bucket_names":{"type":"array","description":"Document field names","items":{"type":"string"}}},"required":["buckets","bucket_names"]},"framework-search-bucket-interface":{"type":"object","description":"Facet Bucket","properties":{"name":{"type":"string","description":"Field name"},"values":{"type":"array","description":"Field values","items":{"$ref":"#/definitions/framework-search-aggregation-value-interface"}}},"required":["name","values"]},"framework-search-aggregation-value-interface":{"type":"object","description":"Interface \\Magento\\Framework\\Api\\Search\\AggregationValueInterface","properties":{"value":{"type":"string","description":"Aggregation"},"metrics":{"type":"array","description":"Metrics","items":{"type":"string"}}},"required":["value","metrics"]},"framework-search-search-criteria-interface":{"type":"object","description":"Interface SearchCriteriaInterface","properties":{"request_name":{"type":"string"},"filter_groups":{"type":"array","description":"A list of filter groups.","items":{"$ref":"#/definitions/framework-search-filter-group"}},"sort_orders":{"type":"array","description":"Sort order.","items":{"$ref":"#/definitions/framework-sort-order"}},"page_size":{"type":"integer","description":"Page size."},"current_page":{"type":"integer","description":"Current page."}},"required":["request_name","filter_groups"]},"sales-data-order-interface":{"type":"object","description":"Order interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"adjustment_negative":{"type":"number","description":"Negative adjustment value."},"adjustment_positive":{"type":"number","description":"Positive adjustment value."},"applied_rule_ids":{"type":"string","description":"Applied rule IDs."},"base_adjustment_negative":{"type":"number","description":"Base negative adjustment value."},"base_adjustment_positive":{"type":"number","description":"Base positive adjustment value."},"base_currency_code":{"type":"string","description":"Base currency code."},"base_discount_amount":{"type":"number","description":"Base discount amount."},"base_discount_canceled":{"type":"number","description":"Base discount canceled."},"base_discount_invoiced":{"type":"number","description":"Base discount invoiced."},"base_discount_refunded":{"type":"number","description":"Base discount refunded."},"base_grand_total":{"type":"number","description":"Base grand total."},"base_discount_tax_compensation_amount":{"type":"number","description":"Base discount tax compensation amount."},"base_discount_tax_compensation_invoiced":{"type":"number","description":"Base discount tax compensation invoiced."},"base_discount_tax_compensation_refunded":{"type":"number","description":"Base discount tax compensation refunded."},"base_shipping_amount":{"type":"number","description":"Base shipping amount."},"base_shipping_canceled":{"type":"number","description":"Base shipping canceled."},"base_shipping_discount_amount":{"type":"number","description":"Base shipping discount amount."},"base_shipping_discount_tax_compensation_amnt":{"type":"number","description":"Base shipping discount tax compensation amount."},"base_shipping_incl_tax":{"type":"number","description":"Base shipping including tax."},"base_shipping_invoiced":{"type":"number","description":"Base shipping invoiced."},"base_shipping_refunded":{"type":"number","description":"Base shipping refunded."},"base_shipping_tax_amount":{"type":"number","description":"Base shipping tax amount."},"base_shipping_tax_refunded":{"type":"number","description":"Base shipping tax refunded."},"base_subtotal":{"type":"number","description":"Base subtotal."},"base_subtotal_canceled":{"type":"number","description":"Base subtotal canceled."},"base_subtotal_incl_tax":{"type":"number","description":"Base subtotal including tax."},"base_subtotal_invoiced":{"type":"number","description":"Base subtotal invoiced."},"base_subtotal_refunded":{"type":"number","description":"Base subtotal refunded."},"base_tax_amount":{"type":"number","description":"Base tax amount."},"base_tax_canceled":{"type":"number","description":"Base tax canceled."},"base_tax_invoiced":{"type":"number","description":"Base tax invoiced."},"base_tax_refunded":{"type":"number","description":"Base tax refunded."},"base_total_canceled":{"type":"number","description":"Base total canceled."},"base_total_due":{"type":"number","description":"Base total due."},"base_total_invoiced":{"type":"number","description":"Base total invoiced."},"base_total_invoiced_cost":{"type":"number","description":"Base total invoiced cost."},"base_total_offline_refunded":{"type":"number","description":"Base total offline refunded."},"base_total_online_refunded":{"type":"number","description":"Base total online refunded."},"base_total_paid":{"type":"number","description":"Base total paid."},"base_total_qty_ordered":{"type":"number","description":"Base total quantity ordered."},"base_total_refunded":{"type":"number","description":"Base total refunded."},"base_to_global_rate":{"type":"number","description":"Base-to-global rate."},"base_to_order_rate":{"type":"number","description":"Base-to-order rate."},"billing_address_id":{"type":"integer","description":"Billing address ID."},"can_ship_partially":{"type":"integer","description":"Can-ship-partially flag value."},"can_ship_partially_item":{"type":"integer","description":"Can-ship-partially-item flag value."},"coupon_code":{"type":"string","description":"Coupon code."},"created_at":{"type":"string","description":"Created-at timestamp."},"customer_dob":{"type":"string","description":"Customer date-of-birth (DOB)."},"customer_email":{"type":"string","description":"Customer email address."},"customer_firstname":{"type":"string","description":"Customer first name."},"customer_gender":{"type":"integer","description":"Customer gender."},"customer_group_id":{"type":"integer","description":"Customer group ID."},"customer_id":{"type":"integer","description":"Customer ID."},"customer_is_guest":{"type":"integer","description":"Customer-is-guest flag value."},"customer_lastname":{"type":"string","description":"Customer last name."},"customer_middlename":{"type":"string","description":"Customer middle name."},"customer_note":{"type":"string","description":"Customer note."},"customer_note_notify":{"type":"integer","description":"Customer-note-notify flag value."},"customer_prefix":{"type":"string","description":"Customer prefix."},"customer_suffix":{"type":"string","description":"Customer suffix."},"customer_taxvat":{"type":"string","description":"Customer value-added tax (VAT)."},"discount_amount":{"type":"number","description":"Discount amount."},"discount_canceled":{"type":"number","description":"Discount canceled."},"discount_description":{"type":"string","description":"Discount description."},"discount_invoiced":{"type":"number","description":"Discount invoiced."},"discount_refunded":{"type":"number","description":"Discount refunded amount."},"edit_increment":{"type":"integer","description":"Edit increment value."},"email_sent":{"type":"integer","description":"Email-sent flag value."},"entity_id":{"type":"integer","description":"Order ID."},"ext_customer_id":{"type":"string","description":"External customer ID."},"ext_order_id":{"type":"string","description":"External order ID."},"forced_shipment_with_invoice":{"type":"integer","description":"Forced-shipment-with-invoice flag value."},"global_currency_code":{"type":"string","description":"Global currency code."},"grand_total":{"type":"number","description":"Grand total."},"discount_tax_compensation_amount":{"type":"number","description":"Discount tax compensation amount."},"discount_tax_compensation_invoiced":{"type":"number","description":"Discount tax compensation invoiced amount."},"discount_tax_compensation_refunded":{"type":"number","description":"Discount tax compensation refunded amount."},"hold_before_state":{"type":"string","description":"Hold before state."},"hold_before_status":{"type":"string","description":"Hold before status."},"increment_id":{"type":"string","description":"Increment ID."},"is_virtual":{"type":"integer","description":"Is-virtual flag value."},"order_currency_code":{"type":"string","description":"Order currency code."},"original_increment_id":{"type":"string","description":"Original increment ID."},"payment_authorization_amount":{"type":"number","description":"Payment authorization amount."},"payment_auth_expiration":{"type":"integer","description":"Payment authorization expiration date."},"protect_code":{"type":"string","description":"Protect code."},"quote_address_id":{"type":"integer","description":"Quote address ID."},"quote_id":{"type":"integer","description":"Quote ID."},"relation_child_id":{"type":"string","description":"Relation child ID."},"relation_child_real_id":{"type":"string","description":"Relation child real ID."},"relation_parent_id":{"type":"string","description":"Relation parent ID."},"relation_parent_real_id":{"type":"string","description":"Relation parent real ID."},"remote_ip":{"type":"string","description":"Remote IP address."},"shipping_amount":{"type":"number","description":"Shipping amount."},"shipping_canceled":{"type":"number","description":"Shipping canceled amount."},"shipping_description":{"type":"string","description":"Shipping description."},"shipping_discount_amount":{"type":"number","description":"Shipping discount amount."},"shipping_discount_tax_compensation_amount":{"type":"number","description":"Shipping discount tax compensation amount."},"shipping_incl_tax":{"type":"number","description":"Shipping including tax amount."},"shipping_invoiced":{"type":"number","description":"Shipping invoiced amount."},"shipping_refunded":{"type":"number","description":"Shipping refunded amount."},"shipping_tax_amount":{"type":"number","description":"Shipping tax amount."},"shipping_tax_refunded":{"type":"number","description":"Shipping tax refunded amount."},"state":{"type":"string","description":"State."},"status":{"type":"string","description":"Status."},"store_currency_code":{"type":"string","description":"Store currency code."},"store_id":{"type":"integer","description":"Store ID."},"store_name":{"type":"string","description":"Store name."},"store_to_base_rate":{"type":"number","description":"Store-to-base rate."},"store_to_order_rate":{"type":"number","description":"Store-to-order rate."},"subtotal":{"type":"number","description":"Subtotal."},"subtotal_canceled":{"type":"number","description":"Subtotal canceled amount."},"subtotal_incl_tax":{"type":"number","description":"Subtotal including tax amount."},"subtotal_invoiced":{"type":"number","description":"Subtotal invoiced amount."},"subtotal_refunded":{"type":"number","description":"Subtotal refunded amount."},"tax_amount":{"type":"number","description":"Tax amount."},"tax_canceled":{"type":"number","description":"Tax canceled amount."},"tax_invoiced":{"type":"number","description":"Tax invoiced amount."},"tax_refunded":{"type":"number","description":"Tax refunded amount."},"total_canceled":{"type":"number","description":"Total canceled."},"total_due":{"type":"number","description":"Total due."},"total_invoiced":{"type":"number","description":"Total invoiced amount."},"total_item_count":{"type":"integer","description":"Total item count."},"total_offline_refunded":{"type":"number","description":"Total offline refunded amount."},"total_online_refunded":{"type":"number","description":"Total online refunded amount."},"total_paid":{"type":"number","description":"Total paid."},"total_qty_ordered":{"type":"number","description":"Total quantity ordered."},"total_refunded":{"type":"number","description":"Total amount refunded."},"updated_at":{"type":"string","description":"Updated-at timestamp."},"weight":{"type":"number","description":"Weight."},"x_forwarded_for":{"type":"string","description":"X-Forwarded-For field value."},"items":{"type":"array","description":"Array of items.","items":{"$ref":"#/definitions/sales-data-order-item-interface"}},"billing_address":{"$ref":"#/definitions/sales-data-order-address-interface"},"payment":{"$ref":"#/definitions/sales-data-order-payment-interface"},"status_histories":{"type":"array","description":"Array of status histories.","items":{"$ref":"#/definitions/sales-data-order-status-history-interface"}},"extension_attributes":{"$ref":"#/definitions/sales-data-order-extension-interface"}},"required":["base_grand_total","customer_email","grand_total","items"]},"sales-data-order-item-interface":{"type":"object","description":"Order item interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"additional_data":{"type":"string","description":"Additional data."},"amount_refunded":{"type":"number","description":"Amount refunded."},"applied_rule_ids":{"type":"string","description":"Applied rule IDs."},"base_amount_refunded":{"type":"number","description":"Base amount refunded."},"base_cost":{"type":"number","description":"Base cost."},"base_discount_amount":{"type":"number","description":"Base discount amount."},"base_discount_invoiced":{"type":"number","description":"Base discount invoiced."},"base_discount_refunded":{"type":"number","description":"Base discount refunded."},"base_discount_tax_compensation_amount":{"type":"number","description":"Base discount tax compensation amount."},"base_discount_tax_compensation_invoiced":{"type":"number","description":"Base discount tax compensation invoiced."},"base_discount_tax_compensation_refunded":{"type":"number","description":"Base discount tax compensation refunded."},"base_original_price":{"type":"number","description":"Base original price."},"base_price":{"type":"number","description":"Base price."},"base_price_incl_tax":{"type":"number","description":"Base price including tax."},"base_row_invoiced":{"type":"number","description":"Base row invoiced."},"base_row_total":{"type":"number","description":"Base row total."},"base_row_total_incl_tax":{"type":"number","description":"Base row total including tax."},"base_tax_amount":{"type":"number","description":"Base tax amount."},"base_tax_before_discount":{"type":"number","description":"Base tax before discount."},"base_tax_invoiced":{"type":"number","description":"Base tax invoiced."},"base_tax_refunded":{"type":"number","description":"Base tax refunded."},"base_weee_tax_applied_amount":{"type":"number","description":"Base WEEE tax applied amount."},"base_weee_tax_applied_row_amnt":{"type":"number","description":"Base WEEE tax applied row amount."},"base_weee_tax_disposition":{"type":"number","description":"Base WEEE tax disposition."},"base_weee_tax_row_disposition":{"type":"number","description":"Base WEEE tax row disposition."},"created_at":{"type":"string","description":"Created-at timestamp."},"description":{"type":"string","description":"Description."},"discount_amount":{"type":"number","description":"Discount amount."},"discount_invoiced":{"type":"number","description":"Discount invoiced."},"discount_percent":{"type":"number","description":"Discount percent."},"discount_refunded":{"type":"number","description":"Discount refunded."},"event_id":{"type":"integer","description":"Event ID."},"ext_order_item_id":{"type":"string","description":"External order item ID."},"free_shipping":{"type":"integer","description":"Free-shipping flag value."},"gw_base_price":{"type":"number","description":"GW base price."},"gw_base_price_invoiced":{"type":"number","description":"GW base price invoiced."},"gw_base_price_refunded":{"type":"number","description":"GW base price refunded."},"gw_base_tax_amount":{"type":"number","description":"GW base tax amount."},"gw_base_tax_amount_invoiced":{"type":"number","description":"GW base tax amount invoiced."},"gw_base_tax_amount_refunded":{"type":"number","description":"GW base tax amount refunded."},"gw_id":{"type":"integer","description":"GW ID."},"gw_price":{"type":"number","description":"GW price."},"gw_price_invoiced":{"type":"number","description":"GW price invoiced."},"gw_price_refunded":{"type":"number","description":"GW price refunded."},"gw_tax_amount":{"type":"number","description":"GW tax amount."},"gw_tax_amount_invoiced":{"type":"number","description":"GW tax amount invoiced."},"gw_tax_amount_refunded":{"type":"number","description":"GW tax amount refunded."},"discount_tax_compensation_amount":{"type":"number","description":"Discount tax compensation amount."},"discount_tax_compensation_canceled":{"type":"number","description":"Discount tax compensation canceled."},"discount_tax_compensation_invoiced":{"type":"number","description":"Discount tax compensation invoiced."},"discount_tax_compensation_refunded":{"type":"number","description":"Discount tax compensation refunded."},"is_qty_decimal":{"type":"integer","description":"Is-quantity-decimal flag value."},"is_virtual":{"type":"integer","description":"Is-virtual flag value."},"item_id":{"type":"integer","description":"Item ID."},"locked_do_invoice":{"type":"integer","description":"Locked DO invoice flag value."},"locked_do_ship":{"type":"integer","description":"Locked DO ship flag value."},"name":{"type":"string","description":"Name."},"no_discount":{"type":"integer","description":"No-discount flag value."},"order_id":{"type":"integer","description":"Order ID."},"original_price":{"type":"number","description":"Original price."},"parent_item_id":{"type":"integer","description":"Parent item ID."},"price":{"type":"number","description":"Price."},"price_incl_tax":{"type":"number","description":"Price including tax."},"product_id":{"type":"integer","description":"Product ID."},"product_type":{"type":"string","description":"Product type."},"qty_backordered":{"type":"number","description":"Quantity backordered."},"qty_canceled":{"type":"number","description":"Quantity canceled."},"qty_invoiced":{"type":"number","description":"Quantity invoiced."},"qty_ordered":{"type":"number","description":"Quantity ordered."},"qty_refunded":{"type":"number","description":"Quantity refunded."},"qty_returned":{"type":"number","description":"Quantity returned."},"qty_shipped":{"type":"number","description":"Quantity shipped."},"quote_item_id":{"type":"integer","description":"Quote item ID."},"row_invoiced":{"type":"number","description":"Row invoiced."},"row_total":{"type":"number","description":"Row total."},"row_total_incl_tax":{"type":"number","description":"Row total including tax."},"row_weight":{"type":"number","description":"Row weight."},"sku":{"type":"string","description":"SKU."},"store_id":{"type":"integer","description":"Store ID."},"tax_amount":{"type":"number","description":"Tax amount."},"tax_before_discount":{"type":"number","description":"Tax before discount."},"tax_canceled":{"type":"number","description":"Tax canceled."},"tax_invoiced":{"type":"number","description":"Tax invoiced."},"tax_percent":{"type":"number","description":"Tax percent."},"tax_refunded":{"type":"number","description":"Tax refunded."},"updated_at":{"type":"string","description":"Updated-at timestamp."},"weee_tax_applied":{"type":"string","description":"WEEE tax applied."},"weee_tax_applied_amount":{"type":"number","description":"WEEE tax applied amount."},"weee_tax_applied_row_amount":{"type":"number","description":"WEEE tax applied row amount."},"weee_tax_disposition":{"type":"number","description":"WEEE tax disposition."},"weee_tax_row_disposition":{"type":"number","description":"WEEE tax row disposition."},"weight":{"type":"number","description":"Weight."},"parent_item":{"$ref":"#/definitions/sales-data-order-item-interface"},"product_option":{"$ref":"#/definitions/catalog-data-product-option-interface"},"extension_attributes":{"$ref":"#/definitions/sales-data-order-item-extension-interface"}},"required":["sku"]},"catalog-data-product-option-interface":{"type":"object","description":"Product option interface","properties":{"extension_attributes":{"$ref":"#/definitions/catalog-data-product-option-extension-interface"}}},"catalog-data-product-option-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Catalog\\Api\\Data\\ProductOptionInterface","properties":{"custom_options":{"type":"array","items":{"$ref":"#/definitions/catalog-data-custom-option-interface"}},"bundle_options":{"type":"array","items":{"$ref":"#/definitions/bundle-data-bundle-option-interface"}},"downloadable_option":{"$ref":"#/definitions/downloadable-data-downloadable-option-interface"},"giftcard_item_option":{"$ref":"#/definitions/gift-card-data-gift-card-option-interface"},"configurable_item_options":{"type":"array","items":{"$ref":"#/definitions/configurable-product-data-configurable-item-option-value-interface"}}}},"sales-data-order-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\OrderItemInterface","properties":{"gift_message":{"$ref":"#/definitions/gift-message-data-message-interface"},"gw_id":{"type":"string"},"gw_base_price":{"type":"string"},"gw_price":{"type":"string"},"gw_base_tax_amount":{"type":"string"},"gw_tax_amount":{"type":"string"},"gw_base_price_invoiced":{"type":"string"},"gw_price_invoiced":{"type":"string"},"gw_base_tax_amount_invoiced":{"type":"string"},"gw_tax_amount_invoiced":{"type":"string"},"gw_base_price_refunded":{"type":"string"},"gw_price_refunded":{"type":"string"},"gw_base_tax_amount_refunded":{"type":"string"},"gw_tax_amount_refunded":{"type":"string"}}},"sales-data-order-address-interface":{"type":"object","description":"Order address interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"address_type":{"type":"string","description":"Address type."},"city":{"type":"string","description":"City."},"company":{"type":"string","description":"Company."},"country_id":{"type":"string","description":"Country ID."},"customer_address_id":{"type":"integer","description":"Country address ID."},"customer_id":{"type":"integer","description":"Customer ID."},"email":{"type":"string","description":"Email address."},"entity_id":{"type":"integer","description":"Order address ID."},"fax":{"type":"string","description":"Fax number."},"firstname":{"type":"string","description":"First name."},"lastname":{"type":"string","description":"Last name."},"middlename":{"type":"string","description":"Middle name."},"parent_id":{"type":"integer","description":"Parent ID."},"postcode":{"type":"string","description":"Postal code."},"prefix":{"type":"string","description":"Prefix."},"region":{"type":"string","description":"Region."},"region_code":{"type":"string","description":"Region code."},"region_id":{"type":"integer","description":"Region ID."},"street":{"type":"array","description":"Array of any street values. Otherwise, null.","items":{"type":"string"}},"suffix":{"type":"string","description":"Suffix."},"telephone":{"type":"string","description":"Telephone number."},"vat_id":{"type":"string","description":"VAT ID."},"vat_is_valid":{"type":"integer","description":"VAT-is-valid flag value."},"vat_request_date":{"type":"string","description":"VAT request date."},"vat_request_id":{"type":"string","description":"VAT request ID."},"vat_request_success":{"type":"integer","description":"VAT-request-success flag value."},"extension_attributes":{"$ref":"#/definitions/sales-data-order-address-extension-interface"}},"required":["address_type","city","country_id","firstname","lastname","postcode","telephone"]},"sales-data-order-address-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\OrderAddressInterface"},"sales-data-order-payment-interface":{"type":"object","description":"Order payment interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"account_status":{"type":"string","description":"Account status."},"additional_data":{"type":"string","description":"Additional data."},"additional_information":{"type":"array","description":"Array of additional information.","items":{"type":"string"}},"address_status":{"type":"string","description":"Address status."},"amount_authorized":{"type":"number","description":"Amount authorized."},"amount_canceled":{"type":"number","description":"Amount canceled."},"amount_ordered":{"type":"number","description":"Amount ordered."},"amount_paid":{"type":"number","description":"Amount paid."},"amount_refunded":{"type":"number","description":"Amount refunded."},"anet_trans_method":{"type":"string","description":"Anet transaction method."},"base_amount_authorized":{"type":"number","description":"Base amount authorized."},"base_amount_canceled":{"type":"number","description":"Base amount canceled."},"base_amount_ordered":{"type":"number","description":"Base amount ordered."},"base_amount_paid":{"type":"number","description":"Base amount paid."},"base_amount_paid_online":{"type":"number","description":"Base amount paid online."},"base_amount_refunded":{"type":"number","description":"Base amount refunded."},"base_amount_refunded_online":{"type":"number","description":"Base amount refunded online."},"base_shipping_amount":{"type":"number","description":"Base shipping amount."},"base_shipping_captured":{"type":"number","description":"Base shipping captured amount."},"base_shipping_refunded":{"type":"number","description":"Base shipping refunded amount."},"cc_approval":{"type":"string","description":"Credit card approval."},"cc_avs_status":{"type":"string","description":"Credit card avs status."},"cc_cid_status":{"type":"string","description":"Credit card CID status."},"cc_debug_request_body":{"type":"string","description":"Credit card debug request body."},"cc_debug_response_body":{"type":"string","description":"Credit card debug response body."},"cc_debug_response_serialized":{"type":"string","description":"Credit card debug response serialized."},"cc_exp_month":{"type":"string","description":"Credit card expiration month."},"cc_exp_year":{"type":"string","description":"Credit card expiration year."},"cc_last4":{"type":"string","description":"Last four digits of the credit card."},"cc_number_enc":{"type":"string","description":"Encrypted credit card number."},"cc_owner":{"type":"string","description":"Credit card number."},"cc_secure_verify":{"type":"string","description":"Credit card secure verify."},"cc_ss_issue":{"type":"string","description":"Credit card SS issue."},"cc_ss_start_month":{"type":"string","description":"Credit card SS start month."},"cc_ss_start_year":{"type":"string","description":"Credit card SS start year."},"cc_status":{"type":"string","description":"Credit card status."},"cc_status_description":{"type":"string","description":"Credit card status description."},"cc_trans_id":{"type":"string","description":"Credit card transaction ID."},"cc_type":{"type":"string","description":"Credit card type."},"echeck_account_name":{"type":"string","description":"eCheck account name."},"echeck_account_type":{"type":"string","description":"eCheck account type."},"echeck_bank_name":{"type":"string","description":"eCheck bank name."},"echeck_routing_number":{"type":"string","description":"eCheck routing number."},"echeck_type":{"type":"string","description":"eCheck type."},"entity_id":{"type":"integer","description":"Entity ID."},"last_trans_id":{"type":"string","description":"Last transaction ID."},"method":{"type":"string","description":"Method."},"parent_id":{"type":"integer","description":"Parent ID."},"po_number":{"type":"string","description":"PO number."},"protection_eligibility":{"type":"string","description":"Protection eligibility."},"quote_payment_id":{"type":"integer","description":"Quote payment ID."},"shipping_amount":{"type":"number","description":"Shipping amount."},"shipping_captured":{"type":"number","description":"Shipping captured."},"shipping_refunded":{"type":"number","description":"Shipping refunded."},"extension_attributes":{"$ref":"#/definitions/sales-data-order-payment-extension-interface"}},"required":["account_status","additional_information","cc_last4","method"]},"sales-data-order-payment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\OrderPaymentInterface","properties":{"vault_payment_token":{"$ref":"#/definitions/vault-data-payment-token-interface"}}},"vault-data-payment-token-interface":{"type":"object","description":"Gateway vault payment token interface.","properties":{"entity_id":{"type":"integer","description":"Entity ID."},"customer_id":{"type":"integer","description":"Customer ID."},"public_hash":{"type":"string","description":"Public hash"},"payment_method_code":{"type":"string","description":"Payment method code"},"type":{"type":"string","description":"Type"},"created_at":{"type":"string","description":"Token creation timestamp"},"expires_at":{"type":"string","description":"Token expiration timestamp"},"gateway_token":{"type":"string","description":"Gateway token ID"},"token_details":{"type":"string","description":"Token details"},"is_active":{"type":"boolean","description":"Is active."},"is_visible":{"type":"boolean","description":"Is visible."}},"required":["public_hash","payment_method_code","type","gateway_token","token_details","is_active","is_visible"]},"sales-data-order-status-history-interface":{"type":"object","description":"Order status history interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"comment":{"type":"string","description":"Comment."},"created_at":{"type":"string","description":"Created-at timestamp."},"entity_id":{"type":"integer","description":"Order status history ID."},"entity_name":{"type":"string","description":"Entity name."},"is_customer_notified":{"type":"integer","description":"Is-customer-notified flag value."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."},"parent_id":{"type":"integer","description":"Parent ID."},"status":{"type":"string","description":"Status."},"extension_attributes":{"$ref":"#/definitions/sales-data-order-status-history-extension-interface"}},"required":["comment","is_customer_notified","is_visible_on_front","parent_id"]},"sales-data-order-status-history-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\OrderStatusHistoryInterface"},"sales-data-order-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\OrderInterface","properties":{"shipping_assignments":{"type":"array","items":{"$ref":"#/definitions/sales-data-shipping-assignment-interface"}},"base_customer_balance_amount":{"type":"number"},"customer_balance_amount":{"type":"number"},"base_customer_balance_invoiced":{"type":"number"},"customer_balance_invoiced":{"type":"number"},"base_customer_balance_refunded":{"type":"number"},"customer_balance_refunded":{"type":"number"},"base_customer_balance_total_refunded":{"type":"number"},"customer_balance_total_refunded":{"type":"number"},"gift_cards":{"type":"array","items":{"$ref":"#/definitions/gift-card-account-data-gift-card-interface"}},"base_gift_cards_amount":{"type":"number"},"gift_cards_amount":{"type":"number"},"base_gift_cards_invoiced":{"type":"number"},"gift_cards_invoiced":{"type":"number"},"base_gift_cards_refunded":{"type":"number"},"gift_cards_refunded":{"type":"number"},"applied_taxes":{"type":"array","items":{"$ref":"#/definitions/tax-data-order-tax-details-applied-tax-interface"}},"item_applied_taxes":{"type":"array","items":{"$ref":"#/definitions/tax-data-order-tax-details-item-interface"}},"converting_from_quote":{"type":"boolean"},"gift_message":{"$ref":"#/definitions/gift-message-data-message-interface"},"gw_id":{"type":"string"},"gw_allow_gift_receipt":{"type":"string"},"gw_add_card":{"type":"string"},"gw_base_price":{"type":"string"},"gw_price":{"type":"string"},"gw_items_base_price":{"type":"string"},"gw_items_price":{"type":"string"},"gw_card_base_price":{"type":"string"},"gw_card_price":{"type":"string"},"gw_base_tax_amount":{"type":"string"},"gw_tax_amount":{"type":"string"},"gw_items_base_tax_amount":{"type":"string"},"gw_items_tax_amount":{"type":"string"},"gw_card_base_tax_amount":{"type":"string"},"gw_card_tax_amount":{"type":"string"},"gw_base_price_incl_tax":{"type":"string"},"gw_price_incl_tax":{"type":"string"},"gw_items_base_price_incl_tax":{"type":"string"},"gw_items_price_incl_tax":{"type":"string"},"gw_card_base_price_incl_tax":{"type":"string"},"gw_card_price_incl_tax":{"type":"string"},"gw_base_price_invoiced":{"type":"string"},"gw_price_invoiced":{"type":"string"},"gw_items_base_price_invoiced":{"type":"string"},"gw_items_price_invoiced":{"type":"string"},"gw_card_base_price_invoiced":{"type":"string"},"gw_card_price_invoiced":{"type":"string"},"gw_base_tax_amount_invoiced":{"type":"string"},"gw_tax_amount_invoiced":{"type":"string"},"gw_items_base_tax_invoiced":{"type":"string"},"gw_items_tax_invoiced":{"type":"string"},"gw_card_base_tax_invoiced":{"type":"string"},"gw_card_tax_invoiced":{"type":"string"},"gw_base_price_refunded":{"type":"string"},"gw_price_refunded":{"type":"string"},"gw_items_base_price_refunded":{"type":"string"},"gw_items_price_refunded":{"type":"string"},"gw_card_base_price_refunded":{"type":"string"},"gw_card_price_refunded":{"type":"string"},"gw_base_tax_amount_refunded":{"type":"string"},"gw_tax_amount_refunded":{"type":"string"},"gw_items_base_tax_refunded":{"type":"string"},"gw_items_tax_refunded":{"type":"string"},"gw_card_base_tax_refunded":{"type":"string"},"gw_card_tax_refunded":{"type":"string"}}},"sales-data-shipping-assignment-interface":{"type":"object","description":"Interface ShippingAssignmentInterface","properties":{"shipping":{"$ref":"#/definitions/sales-data-shipping-interface"},"items":{"type":"array","description":"Order items of shipping assignment","items":{"$ref":"#/definitions/sales-data-order-item-interface"}},"stock_id":{"type":"integer","description":"Stock id"},"extension_attributes":{"$ref":"#/definitions/sales-data-shipping-assignment-extension-interface"}},"required":["shipping","items"]},"sales-data-shipping-interface":{"type":"object","description":"Interface ShippingInterface","properties":{"address":{"$ref":"#/definitions/sales-data-order-address-interface"},"method":{"type":"string","description":"Shipping method"},"total":{"$ref":"#/definitions/sales-data-total-interface"},"extension_attributes":{"$ref":"#/definitions/sales-data-shipping-extension-interface"}}},"sales-data-total-interface":{"type":"object","description":"Interface TotalInterface","properties":{"base_shipping_amount":{"type":"number","description":"Base shipping amount."},"base_shipping_canceled":{"type":"number","description":"Base shipping canceled."},"base_shipping_discount_amount":{"type":"number","description":"Base shipping discount amount."},"base_shipping_discount_tax_compensation_amnt":{"type":"number","description":"Base shipping discount tax compensation amount."},"base_shipping_incl_tax":{"type":"number","description":"Base shipping including tax."},"base_shipping_invoiced":{"type":"number","description":"Base shipping invoiced."},"base_shipping_refunded":{"type":"number","description":"Base shipping refunded."},"base_shipping_tax_amount":{"type":"number","description":"Base shipping tax amount."},"base_shipping_tax_refunded":{"type":"number","description":"Base shipping tax refunded."},"shipping_amount":{"type":"number","description":"Shipping amount."},"shipping_canceled":{"type":"number","description":"Shipping canceled amount."},"shipping_discount_amount":{"type":"number","description":"Shipping discount amount."},"shipping_discount_tax_compensation_amount":{"type":"number","description":"Shipping discount tax compensation amount."},"shipping_incl_tax":{"type":"number","description":"Shipping including tax amount."},"shipping_invoiced":{"type":"number","description":"Shipping invoiced amount."},"shipping_refunded":{"type":"number","description":"Shipping refunded amount."},"shipping_tax_amount":{"type":"number","description":"Shipping tax amount."},"shipping_tax_refunded":{"type":"number","description":"Shipping tax refunded amount."},"extension_attributes":{"$ref":"#/definitions/sales-data-total-extension-interface"}}},"sales-data-total-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\TotalInterface"},"sales-data-shipping-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShippingInterface"},"sales-data-shipping-assignment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShippingAssignmentInterface"},"gift-card-account-data-gift-card-interface":{"type":"object","description":"Gift Card data","properties":{"id":{"type":"integer","description":"Id"},"code":{"type":"string","description":"Code"},"amount":{"type":"number","description":"Amount"},"base_amount":{"type":"number","description":"Base Amount"}},"required":["id","code","amount","base_amount"]},"tax-data-order-tax-details-applied-tax-interface":{"type":"object","description":"Interface OrderTaxDetailsAppliedTaxInterface","properties":{"code":{"type":"string","description":"Code"},"title":{"type":"string","description":"Title"},"percent":{"type":"number","description":"Tax Percent"},"amount":{"type":"number","description":"Tax amount"},"base_amount":{"type":"number","description":"Tax amount in base currency"},"extension_attributes":{"$ref":"#/definitions/tax-data-order-tax-details-applied-tax-extension-interface"}},"required":["amount","base_amount"]},"tax-data-order-tax-details-applied-tax-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\OrderTaxDetailsAppliedTaxInterface","properties":{"rates":{"type":"array","items":{"$ref":"#/definitions/tax-data-applied-tax-rate-interface"}}}},"tax-data-applied-tax-rate-interface":{"type":"object","description":"Applied tax rate interface.","properties":{"code":{"type":"string","description":"Code"},"title":{"type":"string","description":"Title"},"percent":{"type":"number","description":"Tax Percent"},"extension_attributes":{"$ref":"#/definitions/tax-data-applied-tax-rate-extension-interface"}}},"tax-data-applied-tax-rate-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\AppliedTaxRateInterface"},"tax-data-order-tax-details-item-interface":{"type":"object","description":"Interface OrderTaxDetailsItemInterface","properties":{"type":{"type":"string","description":"Type (shipping, product, weee, gift wrapping, etc)"},"item_id":{"type":"integer","description":"Item id if this item is a product"},"associated_item_id":{"type":"integer","description":"Associated item id if this item is associated with another item, null otherwise"},"applied_taxes":{"type":"array","description":"Applied taxes","items":{"$ref":"#/definitions/tax-data-order-tax-details-applied-tax-interface"}},"extension_attributes":{"$ref":"#/definitions/tax-data-order-tax-details-item-extension-interface"}}},"tax-data-order-tax-details-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\OrderTaxDetailsItemInterface"},"sales-data-order-search-result-interface":{"type":"object","description":"Order search result interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-order-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-order-status-history-search-result-interface":{"type":"object","description":"Order status history search result interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-order-status-history-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-order-item-search-result-interface":{"type":"object","description":"Order item search result interface. An order is a document that a web store issues to a customer. Magento generates a sales order that lists the product items, billing and shipping addresses, and shipping and payment methods. A corresponding external document, known as a purchase order, is emailed to the customer.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-order-item-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-invoice-interface":{"type":"object","description":"Invoice interface. An invoice is a record of the receipt of payment for an order.","properties":{"base_currency_code":{"type":"string","description":"Base currency code."},"base_discount_amount":{"type":"number","description":"Base discount amount."},"base_grand_total":{"type":"number","description":"Base grand total."},"base_discount_tax_compensation_amount":{"type":"number","description":"Base discount tax compensation amount."},"base_shipping_amount":{"type":"number","description":"Base shipping amount."},"base_shipping_discount_tax_compensation_amnt":{"type":"number","description":"Base shipping discount tax compensation amount."},"base_shipping_incl_tax":{"type":"number","description":"Base shipping including tax."},"base_shipping_tax_amount":{"type":"number","description":"Base shipping tax amount."},"base_subtotal":{"type":"number","description":"Base subtotal."},"base_subtotal_incl_tax":{"type":"number","description":"Base subtotal including tax."},"base_tax_amount":{"type":"number","description":"Base tax amount."},"base_total_refunded":{"type":"number","description":"Base total refunded."},"base_to_global_rate":{"type":"number","description":"Base-to-global rate."},"base_to_order_rate":{"type":"number","description":"Base-to-order rate."},"billing_address_id":{"type":"integer","description":"Billing address ID."},"can_void_flag":{"type":"integer","description":"Can void flag value."},"created_at":{"type":"string","description":"Created-at timestamp."},"discount_amount":{"type":"number","description":"Discount amount."},"discount_description":{"type":"string","description":"Discount description."},"email_sent":{"type":"integer","description":"Email-sent flag value."},"entity_id":{"type":"integer","description":"Invoice ID."},"global_currency_code":{"type":"string","description":"Global currency code."},"grand_total":{"type":"number","description":"Grand total."},"discount_tax_compensation_amount":{"type":"number","description":"Discount tax compensation amount."},"increment_id":{"type":"string","description":"Increment ID."},"is_used_for_refund":{"type":"integer","description":"Is-used-for-refund flag value."},"order_currency_code":{"type":"string","description":"Order currency code."},"order_id":{"type":"integer","description":"Order ID."},"shipping_address_id":{"type":"integer","description":"Shipping address ID."},"shipping_amount":{"type":"number","description":"Shipping amount."},"shipping_discount_tax_compensation_amount":{"type":"number","description":"Shipping discount tax compensation amount."},"shipping_incl_tax":{"type":"number","description":"Shipping including tax."},"shipping_tax_amount":{"type":"number","description":"Shipping tax amount."},"state":{"type":"integer","description":"State."},"store_currency_code":{"type":"string","description":"Store currency code."},"store_id":{"type":"integer","description":"Store ID."},"store_to_base_rate":{"type":"number","description":"Store-to-base rate."},"store_to_order_rate":{"type":"number","description":"Store-to-order rate."},"subtotal":{"type":"number","description":"Subtotal."},"subtotal_incl_tax":{"type":"number","description":"Subtotal including tax."},"tax_amount":{"type":"number","description":"Tax amount."},"total_qty":{"type":"number","description":"Total quantity."},"transaction_id":{"type":"string","description":"Transaction ID."},"updated_at":{"type":"string","description":"Updated-at timestamp."},"items":{"type":"array","description":"Array of invoice items.","items":{"$ref":"#/definitions/sales-data-invoice-item-interface"}},"comments":{"type":"array","description":"Array of any invoice comments. Otherwise, null.","items":{"$ref":"#/definitions/sales-data-invoice-comment-interface"}},"extension_attributes":{"$ref":"#/definitions/sales-data-invoice-extension-interface"}},"required":["order_id","total_qty","items"]},"sales-data-invoice-item-interface":{"type":"object","description":"Invoice item interface. An invoice is a record of the receipt of payment for an order. An invoice item is a purchased item in an invoice.","properties":{"additional_data":{"type":"string","description":"Additional data."},"base_cost":{"type":"number","description":"Base cost."},"base_discount_amount":{"type":"number","description":"Base discount amount."},"base_discount_tax_compensation_amount":{"type":"number","description":"Base discount tax compensation amount."},"base_price":{"type":"number","description":"Base price."},"base_price_incl_tax":{"type":"number","description":"Base price including tax."},"base_row_total":{"type":"number","description":"Base row total."},"base_row_total_incl_tax":{"type":"number","description":"Base row total including tax."},"base_tax_amount":{"type":"number","description":"Base tax amount."},"description":{"type":"string","description":"Description."},"discount_amount":{"type":"number","description":"Discount amount."},"entity_id":{"type":"integer","description":"Invoice item ID."},"discount_tax_compensation_amount":{"type":"number","description":"Discount tax compensation amount."},"name":{"type":"string","description":"Name."},"parent_id":{"type":"integer","description":"Parent ID."},"price":{"type":"number","description":"Price."},"price_incl_tax":{"type":"number","description":"Price including tax."},"product_id":{"type":"integer","description":"Product ID."},"row_total":{"type":"number","description":"Row total."},"row_total_incl_tax":{"type":"number","description":"Row total including tax."},"sku":{"type":"string","description":"SKU."},"tax_amount":{"type":"number","description":"Tax amount."},"extension_attributes":{"$ref":"#/definitions/sales-data-invoice-item-extension-interface"},"order_item_id":{"type":"integer","description":"Order item ID."},"qty":{"type":"number","description":"Quantity."}},"required":["sku","order_item_id","qty"]},"sales-data-invoice-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\InvoiceItemInterface"},"sales-data-invoice-comment-interface":{"type":"object","description":"Invoice comment interface. An invoice is a record of the receipt of payment for an order. An invoice can include comments that detail the invoice history.","properties":{"is_customer_notified":{"type":"integer","description":"Is-customer-notified flag value."},"parent_id":{"type":"integer","description":"Parent ID."},"extension_attributes":{"$ref":"#/definitions/sales-data-invoice-comment-extension-interface"},"comment":{"type":"string","description":"Comment."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."},"created_at":{"type":"string","description":"Created-at timestamp."},"entity_id":{"type":"integer","description":"Invoice ID."}},"required":["is_customer_notified","parent_id","comment","is_visible_on_front"]},"sales-data-invoice-comment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\InvoiceCommentInterface"},"sales-data-invoice-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\InvoiceInterface","properties":{"base_customer_balance_amount":{"type":"number"},"customer_balance_amount":{"type":"number"},"base_gift_cards_amount":{"type":"number"},"gift_cards_amount":{"type":"number"},"gw_base_price":{"type":"string"},"gw_price":{"type":"string"},"gw_items_base_price":{"type":"string"},"gw_items_price":{"type":"string"},"gw_card_base_price":{"type":"string"},"gw_card_price":{"type":"string"},"gw_base_tax_amount":{"type":"string"},"gw_tax_amount":{"type":"string"},"gw_items_base_tax_amount":{"type":"string"},"gw_items_tax_amount":{"type":"string"},"gw_card_base_tax_amount":{"type":"string"},"gw_card_tax_amount":{"type":"string"},"invoice_api_test_attribute":{"$ref":"#/definitions/user-data-user-interface"}}},"sales-data-invoice-search-result-interface":{"type":"object","description":"Invoice search result interface. An invoice is a record of the receipt of payment for an order.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-invoice-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-invoice-comment-search-result-interface":{"type":"object","description":"Invoice comment search result interface. An invoice is a record of the receipt of payment for an order. An invoice can include comments that detail the invoice history.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-invoice-comment-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-creditmemo-item-creation-interface":{"type":"object","description":"Interface CreditmemoItemCreationInterface","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-creditmemo-item-creation-extension-interface"},"order_item_id":{"type":"integer","description":"Order item ID."},"qty":{"type":"number","description":"Quantity."}},"required":["order_item_id","qty"]},"sales-data-creditmemo-item-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\CreditmemoItemCreationInterface"},"sales-data-creditmemo-comment-creation-interface":{"type":"object","description":"Interface CreditmemoCommentCreationInterface","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-creditmemo-comment-creation-extension-interface"},"comment":{"type":"string","description":"Comment."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."}},"required":["comment","is_visible_on_front"]},"sales-data-creditmemo-comment-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\CreditmemoCommentCreationInterface"},"sales-data-creditmemo-creation-arguments-interface":{"type":"object","description":"Interface CreditmemoCreationArgumentsInterface","properties":{"shipping_amount":{"type":"number","description":"Credit memo shipping amount."},"adjustment_positive":{"type":"number","description":"Credit memo positive adjustment."},"adjustment_negative":{"type":"number","description":"Credit memo negative adjustment."},"extension_attributes":{"$ref":"#/definitions/sales-data-creditmemo-creation-arguments-extension-interface"}}},"sales-data-creditmemo-creation-arguments-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\CreditmemoCreationArgumentsInterface","properties":{"return_to_stock_items":{"type":"array","items":{"type":"integer"}}}},"sales-data-creditmemo-comment-search-result-interface":{"type":"object","description":"Credit memo comment search result interface. After a customer places and pays for an order and an invoice has been issued, the merchant can create a credit memo to refund all or part of the amount paid for any returned or undelivered items. The memo restores funds to the customer account so that the customer can make future purchases. A credit memo usually includes comments that detail why the credit memo amount was credited to the customer.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-creditmemo-comment-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-creditmemo-comment-interface":{"type":"object","description":"Credit memo comment interface. After a customer places and pays for an order and an invoice has been issued, the merchant can create a credit memo to refund all or part of the amount paid for any returned or undelivered items. The memo restores funds to the customer account so that the customer can make future purchases. A credit memo usually includes comments that detail why the credit memo amount was credited to the customer.","properties":{"comment":{"type":"string","description":"Comment."},"created_at":{"type":"string","description":"Created-at timestamp."},"entity_id":{"type":"integer","description":"Credit memo ID."},"is_customer_notified":{"type":"integer","description":"Is-customer-notified flag value."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."},"parent_id":{"type":"integer","description":"Parent ID."},"extension_attributes":{"$ref":"#/definitions/sales-data-creditmemo-comment-extension-interface"}},"required":["comment","is_customer_notified","is_visible_on_front","parent_id"]},"sales-data-creditmemo-comment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\CreditmemoCommentInterface"},"sales-data-creditmemo-interface":{"type":"object","description":"Credit memo interface. After a customer places and pays for an order and an invoice has been issued, the merchant can create a credit memo to refund all or part of the amount paid for any returned or undelivered items. The memo restores funds to the customer account so that the customer can make future purchases.","properties":{"adjustment":{"type":"number","description":"Credit memo adjustment."},"adjustment_negative":{"type":"number","description":"Credit memo negative adjustment."},"adjustment_positive":{"type":"number","description":"Credit memo positive adjustment."},"base_adjustment":{"type":"number","description":"Credit memo base adjustment."},"base_adjustment_negative":{"type":"number","description":"Credit memo negative base adjustment."},"base_adjustment_positive":{"type":"number","description":"Credit memo positive base adjustment."},"base_currency_code":{"type":"string","description":"Credit memo base currency code."},"base_discount_amount":{"type":"number","description":"Credit memo base discount amount."},"base_grand_total":{"type":"number","description":"Credit memo base grand total."},"base_discount_tax_compensation_amount":{"type":"number","description":"Credit memo base discount tax compensation amount."},"base_shipping_amount":{"type":"number","description":"Credit memo base shipping amount."},"base_shipping_discount_tax_compensation_amnt":{"type":"number","description":"Credit memo base shipping discount tax compensation amount."},"base_shipping_incl_tax":{"type":"number","description":"Credit memo base shipping including tax."},"base_shipping_tax_amount":{"type":"number","description":"Credit memo base shipping tax amount."},"base_subtotal":{"type":"number","description":"Credit memo base subtotal."},"base_subtotal_incl_tax":{"type":"number","description":"Credit memo base subtotal including tax."},"base_tax_amount":{"type":"number","description":"Credit memo base tax amount."},"base_to_global_rate":{"type":"number","description":"Credit memo base-to-global rate."},"base_to_order_rate":{"type":"number","description":"Credit memo base-to-order rate."},"billing_address_id":{"type":"integer","description":"Credit memo billing address ID."},"created_at":{"type":"string","description":"Credit memo created-at timestamp."},"creditmemo_status":{"type":"integer","description":"Credit memo status."},"discount_amount":{"type":"number","description":"Credit memo discount amount."},"discount_description":{"type":"string","description":"Credit memo discount description."},"email_sent":{"type":"integer","description":"Credit memo email sent flag value."},"entity_id":{"type":"integer","description":"Credit memo ID."},"global_currency_code":{"type":"string","description":"Credit memo global currency code."},"grand_total":{"type":"number","description":"Credit memo grand total."},"discount_tax_compensation_amount":{"type":"number","description":"Credit memo discount tax compensation amount."},"increment_id":{"type":"string","description":"Credit memo increment ID."},"invoice_id":{"type":"integer","description":"Credit memo invoice ID."},"order_currency_code":{"type":"string","description":"Credit memo order currency code."},"order_id":{"type":"integer","description":"Credit memo order ID."},"shipping_address_id":{"type":"integer","description":"Credit memo shipping address ID."},"shipping_amount":{"type":"number","description":"Credit memo shipping amount."},"shipping_discount_tax_compensation_amount":{"type":"number","description":"Credit memo shipping discount tax compensation amount."},"shipping_incl_tax":{"type":"number","description":"Credit memo shipping including tax."},"shipping_tax_amount":{"type":"number","description":"Credit memo shipping tax amount."},"state":{"type":"integer","description":"Credit memo state."},"store_currency_code":{"type":"string","description":"Credit memo store currency code."},"store_id":{"type":"integer","description":"Credit memo store ID."},"store_to_base_rate":{"type":"number","description":"Credit memo store-to-base rate."},"store_to_order_rate":{"type":"number","description":"Credit memo store-to-order rate."},"subtotal":{"type":"number","description":"Credit memo subtotal."},"subtotal_incl_tax":{"type":"number","description":"Credit memo subtotal including tax."},"tax_amount":{"type":"number","description":"Credit memo tax amount."},"transaction_id":{"type":"string","description":"Credit memo transaction ID."},"updated_at":{"type":"string","description":"Credit memo updated-at timestamp."},"items":{"type":"array","description":"Array of credit memo items.","items":{"$ref":"#/definitions/sales-data-creditmemo-item-interface"}},"comments":{"type":"array","description":"Array of any credit memo comments. Otherwise, null.","items":{"$ref":"#/definitions/sales-data-creditmemo-comment-interface"}},"extension_attributes":{"$ref":"#/definitions/sales-data-creditmemo-extension-interface"}},"required":["order_id","items"]},"sales-data-creditmemo-item-interface":{"type":"object","description":"Credit memo item interface. After a customer places and pays for an order and an invoice has been issued, the merchant can create a credit memo to refund all or part of the amount paid for any returned or undelivered items. The memo restores funds to the customer account so that the customer can make future purchases. A credit memo item is an invoiced item for which a merchant creates a credit memo.","properties":{"additional_data":{"type":"string","description":"Additional data."},"base_cost":{"type":"number","description":"The base cost for a credit memo item."},"base_discount_amount":{"type":"number","description":"The base discount amount for a credit memo item."},"base_discount_tax_compensation_amount":{"type":"number","description":"The base discount tax compensation amount for a credit memo item."},"base_price":{"type":"number","description":"The base price for a credit memo item."},"base_price_incl_tax":{"type":"number","description":"Base price including tax."},"base_row_total":{"type":"number","description":"Base row total."},"base_row_total_incl_tax":{"type":"number","description":"Base row total including tax."},"base_tax_amount":{"type":"number","description":"Base tax amount."},"base_weee_tax_applied_amount":{"type":"number","description":"Base WEEE tax applied amount."},"base_weee_tax_applied_row_amnt":{"type":"number","description":"Base WEEE tax applied row amount."},"base_weee_tax_disposition":{"type":"number","description":"Base WEEE tax disposition."},"base_weee_tax_row_disposition":{"type":"number","description":"Base WEEE tax row disposition."},"description":{"type":"string","description":"Description."},"discount_amount":{"type":"number","description":"Discount amount."},"entity_id":{"type":"integer","description":"Credit memo item ID."},"discount_tax_compensation_amount":{"type":"number","description":"Discount tax compensation amount."},"name":{"type":"string","description":"Name."},"order_item_id":{"type":"integer","description":"Order item ID."},"parent_id":{"type":"integer","description":"Parent ID."},"price":{"type":"number","description":"Price."},"price_incl_tax":{"type":"number","description":"Price including tax."},"product_id":{"type":"integer","description":"Product ID."},"qty":{"type":"number","description":"Quantity."},"row_total":{"type":"number","description":"Row total."},"row_total_incl_tax":{"type":"number","description":"Row total including tax."},"sku":{"type":"string","description":"SKU."},"tax_amount":{"type":"number","description":"Tax amount."},"weee_tax_applied":{"type":"string","description":"WEEE tax applied."},"weee_tax_applied_amount":{"type":"number","description":"WEEE tax applied amount."},"weee_tax_applied_row_amount":{"type":"number","description":"WEEE tax applied row amount."},"weee_tax_disposition":{"type":"number","description":"WEEE tax disposition."},"weee_tax_row_disposition":{"type":"number","description":"WEEE tax row disposition."},"extension_attributes":{"$ref":"#/definitions/sales-data-creditmemo-item-extension-interface"}},"required":["base_cost","base_price","entity_id","order_item_id","qty"]},"sales-data-creditmemo-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\CreditmemoItemInterface"},"sales-data-creditmemo-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\CreditmemoInterface","properties":{"base_customer_balance_amount":{"type":"number"},"customer_balance_amount":{"type":"number"},"base_gift_cards_amount":{"type":"number"},"gift_cards_amount":{"type":"number"},"gw_base_price":{"type":"string"},"gw_price":{"type":"string"},"gw_items_base_price":{"type":"string"},"gw_items_price":{"type":"string"},"gw_card_base_price":{"type":"string"},"gw_card_price":{"type":"string"},"gw_base_tax_amount":{"type":"string"},"gw_tax_amount":{"type":"string"},"gw_items_base_tax_amount":{"type":"string"},"gw_items_tax_amount":{"type":"string"},"gw_card_base_tax_amount":{"type":"string"},"gw_card_tax_amount":{"type":"string"}}},"sales-data-creditmemo-search-result-interface":{"type":"object","description":"Credit memo search result interface. After a customer places and pays for an order and an invoice has been issued, the merchant can create a credit memo to refund all or part of the amount paid for any returned or undelivered items. The memo restores funds to the customer account so that the customer can make future purchases.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-creditmemo-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-shipment-interface":{"type":"object","description":"Shipment interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package.","properties":{"billing_address_id":{"type":"integer","description":"Billing address ID."},"created_at":{"type":"string","description":"Created-at timestamp."},"customer_id":{"type":"integer","description":"Customer ID."},"email_sent":{"type":"integer","description":"Email-sent flag value."},"entity_id":{"type":"integer","description":"Shipment ID."},"increment_id":{"type":"string","description":"Increment ID."},"order_id":{"type":"integer","description":"Order ID."},"packages":{"type":"array","description":"Array of packages, if any. Otherwise, null.","items":{"$ref":"#/definitions/sales-data-shipment-package-interface"}},"shipment_status":{"type":"integer","description":"Shipment status."},"shipping_address_id":{"type":"integer","description":"Shipping address ID."},"shipping_label":{"type":"string","description":"Shipping label."},"store_id":{"type":"integer","description":"Store ID."},"total_qty":{"type":"number","description":"Total quantity."},"total_weight":{"type":"number","description":"Total weight."},"updated_at":{"type":"string","description":"Updated-at timestamp."},"items":{"type":"array","description":"Array of items.","items":{"$ref":"#/definitions/sales-data-shipment-item-interface"}},"tracks":{"type":"array","description":"Array of tracks.","items":{"$ref":"#/definitions/sales-data-shipment-track-interface"}},"comments":{"type":"array","description":"Array of comments.","items":{"$ref":"#/definitions/sales-data-shipment-comment-interface"}},"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-extension-interface"}},"required":["order_id","items","tracks","comments"]},"sales-data-shipment-package-interface":{"type":"object","description":"Shipment package interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package.","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-package-extension-interface"}}},"sales-data-shipment-package-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentPackageInterface"},"sales-data-shipment-item-interface":{"type":"object","description":"Shipment item interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package. A product is an item in a shipment.","properties":{"additional_data":{"type":"string","description":"Additional data."},"description":{"type":"string","description":"Description."},"entity_id":{"type":"integer","description":"Shipment item ID."},"name":{"type":"string","description":"Name."},"parent_id":{"type":"integer","description":"Parent ID."},"price":{"type":"number","description":"Price."},"product_id":{"type":"integer","description":"Product ID."},"row_total":{"type":"number","description":"Row total."},"sku":{"type":"string","description":"SKU."},"weight":{"type":"number","description":"Weight."},"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-item-extension-interface"},"order_item_id":{"type":"integer","description":"Order item ID."},"qty":{"type":"number","description":"Quantity."}},"required":["order_item_id","qty"]},"sales-data-shipment-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentItemInterface"},"sales-data-shipment-track-interface":{"type":"object","description":"Shipment track interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package. Merchants and customers can track shipments.","properties":{"order_id":{"type":"integer","description":"The order_id for the shipment package."},"created_at":{"type":"string","description":"Created-at timestamp."},"entity_id":{"type":"integer","description":"Shipment package ID."},"parent_id":{"type":"integer","description":"Parent ID."},"updated_at":{"type":"string","description":"Updated-at timestamp."},"weight":{"type":"number","description":"Weight."},"qty":{"type":"number","description":"Quantity."},"description":{"type":"string","description":"Description."},"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-track-extension-interface"},"track_number":{"type":"string","description":"Track number."},"title":{"type":"string","description":"Title."},"carrier_code":{"type":"string","description":"Carrier code."}},"required":["order_id","parent_id","weight","qty","description","track_number","title","carrier_code"]},"sales-data-shipment-track-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentTrackInterface"},"sales-data-shipment-comment-interface":{"type":"object","description":"Shipment comment interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package. A shipment document can contain comments.","properties":{"is_customer_notified":{"type":"integer","description":"Is-customer-notified flag value."},"parent_id":{"type":"integer","description":"Parent ID."},"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-comment-extension-interface"},"comment":{"type":"string","description":"Comment."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."},"created_at":{"type":"string","description":"Created-at timestamp."},"entity_id":{"type":"integer","description":"Invoice ID."}},"required":["is_customer_notified","parent_id","comment","is_visible_on_front"]},"sales-data-shipment-comment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentCommentInterface"},"sales-data-shipment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentInterface"},"sales-data-shipment-search-result-interface":{"type":"object","description":"Shipment search result interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-shipment-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-shipment-comment-search-result-interface":{"type":"object","description":"Shipment comment search result interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package. A shipment document can contain comments.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-shipment-comment-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-shipment-item-creation-interface":{"type":"object","description":"Input argument for shipment item creation Interface ShipmentItemCreationInterface","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-item-creation-extension-interface"},"order_item_id":{"type":"integer","description":"Order item ID."},"qty":{"type":"number","description":"Quantity."}},"required":["order_item_id","qty"]},"sales-data-shipment-item-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentItemCreationInterface"},"sales-data-shipment-comment-creation-interface":{"type":"object","description":"Interface ShipmentCommentCreationInterface","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-comment-creation-extension-interface"},"comment":{"type":"string","description":"Comment."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."}},"required":["comment","is_visible_on_front"]},"sales-data-shipment-comment-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentCommentCreationInterface"},"sales-data-shipment-track-creation-interface":{"type":"object","description":"Shipment Track Creation interface.","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-track-creation-extension-interface"},"track_number":{"type":"string","description":"Track number."},"title":{"type":"string","description":"Title."},"carrier_code":{"type":"string","description":"Carrier code."}},"required":["track_number","title","carrier_code"]},"sales-data-shipment-track-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentTrackCreationInterface"},"sales-data-shipment-package-creation-interface":{"type":"object","description":"Shipment package interface. A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This document lists the products and their quantities in the delivery package.","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-package-creation-extension-interface"}}},"sales-data-shipment-package-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentPackageCreationInterface"},"sales-data-shipment-creation-arguments-interface":{"type":"object","description":"Interface for creation arguments for Shipment.","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-shipment-creation-arguments-extension-interface"}}},"sales-data-shipment-creation-arguments-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\ShipmentCreationArgumentsInterface"},"sales-data-transaction-interface":{"type":"object","description":"Transaction interface. A transaction is an interaction between a merchant and a customer such as a purchase, a credit, a refund, and so on.","properties":{"transaction_id":{"type":"integer","description":"Transaction ID."},"parent_id":{"type":"integer","description":"The parent ID for the transaction. Otherwise, null."},"order_id":{"type":"integer","description":"Order ID."},"payment_id":{"type":"integer","description":"Payment ID."},"txn_id":{"type":"string","description":"Transaction business ID."},"parent_txn_id":{"type":"string","description":"Parent transaction business ID."},"txn_type":{"type":"string","description":"Transaction type."},"is_closed":{"type":"integer","description":"Is-closed flag value."},"additional_information":{"type":"array","description":"Array of additional information. Otherwise, null.","items":{"type":"string"}},"created_at":{"type":"string","description":"Created-at timestamp."},"child_transactions":{"type":"array","description":"Array of child transactions.","items":{"$ref":"#/definitions/sales-data-transaction-interface"}},"extension_attributes":{"$ref":"#/definitions/sales-data-transaction-extension-interface"}},"required":["transaction_id","order_id","payment_id","txn_id","parent_txn_id","txn_type","is_closed","created_at","child_transactions"]},"sales-data-transaction-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\TransactionInterface"},"sales-data-transaction-search-result-interface":{"type":"object","description":"Transaction search result interface. A transaction is an interaction between a merchant and a customer such as a purchase, a credit, a refund, and so on.","properties":{"items":{"type":"array","description":"Array of collection items.","items":{"$ref":"#/definitions/sales-data-transaction-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-data-invoice-item-creation-interface":{"type":"object","description":"Input argument for invoice creation Interface InvoiceItemCreationInterface","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-invoice-item-creation-extension-interface"},"order_item_id":{"type":"integer","description":"Order item ID."},"qty":{"type":"number","description":"Quantity."}},"required":["order_item_id","qty"]},"sales-data-invoice-item-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\InvoiceItemCreationInterface"},"sales-data-invoice-comment-creation-interface":{"type":"object","description":"Interface InvoiceCommentCreationInterface","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-invoice-comment-creation-extension-interface"},"comment":{"type":"string","description":"Comment."},"is_visible_on_front":{"type":"integer","description":"Is-visible-on-storefront flag value."}},"required":["comment","is_visible_on_front"]},"sales-data-invoice-comment-creation-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\InvoiceCommentCreationInterface"},"sales-data-invoice-creation-arguments-interface":{"type":"object","description":"Interface for creation arguments for Invoice.","properties":{"extension_attributes":{"$ref":"#/definitions/sales-data-invoice-creation-arguments-extension-interface"}}},"sales-data-invoice-creation-arguments-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Sales\\Api\\Data\\InvoiceCreationArgumentsInterface"},"checkout-data-shipping-information-interface":{"type":"object","description":"Interface ShippingInformationInterface","properties":{"shipping_address":{"$ref":"#/definitions/quote-data-address-interface"},"billing_address":{"$ref":"#/definitions/quote-data-address-interface"},"shipping_method_code":{"type":"string","description":"Shipping method code"},"shipping_carrier_code":{"type":"string","description":"Carrier code"},"extension_attributes":{"$ref":"#/definitions/checkout-data-shipping-information-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["shipping_address","shipping_method_code","shipping_carrier_code"]},"checkout-data-shipping-information-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Checkout\\Api\\Data\\ShippingInformationInterface"},"checkout-data-payment-details-interface":{"type":"object","description":"Interface PaymentDetailsInterface","properties":{"payment_methods":{"type":"array","items":{"$ref":"#/definitions/quote-data-payment-method-interface"}},"totals":{"$ref":"#/definitions/quote-data-totals-interface"},"extension_attributes":{"$ref":"#/definitions/checkout-data-payment-details-extension-interface"}},"required":["payment_methods","totals"]},"checkout-data-payment-details-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Checkout\\Api\\Data\\PaymentDetailsInterface"},"checkout-data-totals-information-interface":{"type":"object","description":"Interface TotalsInformationInterface","properties":{"address":{"$ref":"#/definitions/quote-data-address-interface"},"shipping_method_code":{"type":"string","description":"Shipping method code"},"shipping_carrier_code":{"type":"string","description":"Carrier code"},"extension_attributes":{"$ref":"#/definitions/checkout-data-totals-information-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["address"]},"checkout-data-totals-information-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Checkout\\Api\\Data\\TotalsInformationInterface"},"checkout-agreements-data-agreement-interface":{"type":"object","description":"Interface AgreementInterface","properties":{"agreement_id":{"type":"integer","description":"Agreement ID."},"name":{"type":"string","description":"Agreement name."},"content":{"type":"string","description":"Agreement content."},"content_height":{"type":"string","description":"Agreement content height. Otherwise, null."},"checkbox_text":{"type":"string","description":"Agreement checkbox text."},"is_active":{"type":"boolean","description":"Agreement status."},"is_html":{"type":"boolean","description":"* true - HTML. * false - plain text."},"mode":{"type":"integer","description":"The agreement applied mode."},"extension_attributes":{"$ref":"#/definitions/checkout-agreements-data-agreement-extension-interface"}},"required":["agreement_id","name","content","checkbox_text","is_active","is_html","mode"]},"checkout-agreements-data-agreement-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\CheckoutAgreements\\Api\\Data\\AgreementInterface"},"gift-card-account-data-gift-card-account-interface":{"type":"object","description":"Gift Card Account data","properties":{"gift_cards":{"type":"array","description":"Cards codes","items":{"type":"string"}},"gift_cards_amount":{"type":"number","description":"Cards amount in quote currency"},"base_gift_cards_amount":{"type":"number","description":"Cards amount in base currency"},"gift_cards_amount_used":{"type":"number","description":"Cards amount used in quote currency"},"base_gift_cards_amount_used":{"type":"number","description":"Cards amount used in base currency"},"extension_attributes":{"$ref":"#/definitions/gift-card-account-data-gift-card-account-extension-interface"}},"required":["gift_cards","gift_cards_amount","base_gift_cards_amount","gift_cards_amount_used","base_gift_cards_amount_used"]},"gift-card-account-data-gift-card-account-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\GiftCardAccount\\Api\\Data\\GiftCardAccountInterface"},"tax-data-tax-rate-interface":{"type":"object","description":"Tax rate interface.","properties":{"id":{"type":"integer","description":"Id"},"tax_country_id":{"type":"string","description":"Country id"},"tax_region_id":{"type":"integer","description":"Region id"},"region_name":{"type":"string","description":"Region name"},"tax_postcode":{"type":"string","description":"Postcode"},"zip_is_range":{"type":"integer","description":"Zip is range"},"zip_from":{"type":"integer","description":"Zip range from"},"zip_to":{"type":"integer","description":"Zip range to"},"rate":{"type":"number","description":"Tax rate in percentage"},"code":{"type":"string","description":"Tax rate code"},"titles":{"type":"array","description":"Tax rate titles","items":{"$ref":"#/definitions/tax-data-tax-rate-title-interface"}},"extension_attributes":{"$ref":"#/definitions/tax-data-tax-rate-extension-interface"}},"required":["tax_country_id","rate","code"]},"tax-data-tax-rate-title-interface":{"type":"object","description":"Tax rate title interface.","properties":{"store_id":{"type":"string","description":"Store id"},"value":{"type":"string","description":"Title value"},"extension_attributes":{"$ref":"#/definitions/tax-data-tax-rate-title-extension-interface"}},"required":["store_id","value"]},"tax-data-tax-rate-title-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\TaxRateTitleInterface"},"tax-data-tax-rate-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\TaxRateInterface"},"tax-data-tax-rate-search-results-interface":{"type":"object","description":"Interface for tax rate search results.","properties":{"items":{"type":"array","description":"Items","items":{"$ref":"#/definitions/tax-data-tax-rate-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"tax-data-tax-rule-interface":{"type":"object","description":"Tax rule interface.","properties":{"id":{"type":"integer","description":"Id"},"code":{"type":"string","description":"Tax rule code"},"priority":{"type":"integer","description":"Priority"},"position":{"type":"integer","description":"Sort order."},"customer_tax_class_ids":{"type":"array","description":"Customer tax class id","items":{"type":"integer"}},"product_tax_class_ids":{"type":"array","description":"Product tax class id","items":{"type":"integer"}},"tax_rate_ids":{"type":"array","description":"Tax rate ids","items":{"type":"integer"}},"calculate_subtotal":{"type":"boolean","description":"Calculate subtotal."},"extension_attributes":{"$ref":"#/definitions/tax-data-tax-rule-extension-interface"}},"required":["code","priority","position","customer_tax_class_ids","product_tax_class_ids","tax_rate_ids"]},"tax-data-tax-rule-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\TaxRuleInterface"},"tax-data-tax-rule-search-results-interface":{"type":"object","description":"Interface for tax rule search results.","properties":{"items":{"type":"array","description":"Items","items":{"$ref":"#/definitions/tax-data-tax-rule-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"tax-data-tax-class-interface":{"type":"object","description":"Tax class interface.","properties":{"class_id":{"type":"integer","description":"Tax class ID."},"class_name":{"type":"string","description":"Tax class name."},"class_type":{"type":"string","description":"Tax class type."},"extension_attributes":{"$ref":"#/definitions/tax-data-tax-class-extension-interface"}},"required":["class_name","class_type"]},"tax-data-tax-class-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Tax\\Api\\Data\\TaxClassInterface"},"tax-data-tax-class-search-results-interface":{"type":"object","description":"Interface for tax class search results.","properties":{"items":{"type":"array","description":"Items","items":{"$ref":"#/definitions/tax-data-tax-class-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"gift-wrapping-data-wrapping-interface":{"type":"object","description":"Interface WrappingInterface","properties":{"wrapping_id":{"type":"integer"},"design":{"type":"string"},"status":{"type":"integer"},"base_price":{"type":"number"},"image_name":{"type":"string"},"image_base64_content":{"type":"string"},"base_currency_code":{"type":"string"},"website_ids":{"type":"array","items":{"type":"integer"}},"image_url":{"type":"string","description":"Wrapping image URL."},"extension_attributes":{"$ref":"#/definitions/gift-wrapping-data-wrapping-extension-interface"}},"required":["design","status","base_price"]},"gift-wrapping-data-wrapping-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\GiftWrapping\\Api\\Data\\WrappingInterface"},"gift-wrapping-data-wrapping-search-results-interface":{"type":"object","description":"Interface WrappingSearchResultsInterface","properties":{"items":{"type":"array","description":"Items","items":{"$ref":"#/definitions/gift-wrapping-data-wrapping-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-rule-data-rule-interface":{"type":"object","description":"Interface RuleInterface","properties":{"rule_id":{"type":"integer","description":"Rule id"},"name":{"type":"string","description":"Rule name"},"store_labels":{"type":"array","description":"Display label","items":{"$ref":"#/definitions/sales-rule-data-rule-label-interface"}},"description":{"type":"string","description":"Description"},"website_ids":{"type":"array","description":"A list of websites the rule applies to","items":{"type":"integer"}},"customer_group_ids":{"type":"array","description":"Ids of customer groups that the rule applies to","items":{"type":"integer"}},"from_date":{"type":"string","description":"The start date when the coupon is active"},"to_date":{"type":"string","description":"The end date when the coupon is active"},"uses_per_customer":{"type":"integer","description":"Number of uses per customer"},"is_active":{"type":"boolean","description":"The coupon is active"},"condition":{"$ref":"#/definitions/sales-rule-data-condition-interface"},"action_condition":{"$ref":"#/definitions/sales-rule-data-condition-interface"},"stop_rules_processing":{"type":"boolean","description":"To stop rule processing"},"is_advanced":{"type":"boolean","description":"Is this field needed"},"product_ids":{"type":"array","description":"Product ids","items":{"type":"integer"}},"sort_order":{"type":"integer","description":"Sort order"},"simple_action":{"type":"string","description":"Simple action of the rule"},"discount_amount":{"type":"number","description":"Discount amount"},"discount_qty":{"type":"number","description":"Maximum qty discount is applied"},"discount_step":{"type":"integer","description":"Discount step"},"apply_to_shipping":{"type":"boolean","description":"The rule applies to shipping"},"times_used":{"type":"integer","description":"How many times the rule has been used"},"is_rss":{"type":"boolean","description":"Whether the rule is in RSS"},"coupon_type":{"type":"string","description":"Coupon type"},"use_auto_generation":{"type":"boolean","description":"To auto generate coupon"},"uses_per_coupon":{"type":"integer","description":"Limit of uses per coupon"},"simple_free_shipping":{"type":"string","description":"To grant free shipping"},"extension_attributes":{"$ref":"#/definitions/sales-rule-data-rule-extension-interface"}},"required":["website_ids","customer_group_ids","uses_per_customer","is_active","stop_rules_processing","is_advanced","sort_order","discount_amount","discount_step","apply_to_shipping","times_used","is_rss","coupon_type","use_auto_generation","uses_per_coupon"]},"sales-rule-data-rule-label-interface":{"type":"object","description":"Interface RuleLabelInterface","properties":{"store_id":{"type":"integer","description":"StoreId"},"store_label":{"type":"string","description":"The label for the store"},"extension_attributes":{"$ref":"#/definitions/sales-rule-data-rule-label-extension-interface"}},"required":["store_id","store_label"]},"sales-rule-data-rule-label-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\SalesRule\\Api\\Data\\RuleLabelInterface"},"sales-rule-data-condition-interface":{"type":"object","description":"Interface ConditionInterface","properties":{"condition_type":{"type":"string","description":"Condition type"},"conditions":{"type":"array","description":"List of conditions","items":{"$ref":"#/definitions/sales-rule-data-condition-interface"}},"aggregator_type":{"type":"string","description":"The aggregator type"},"operator":{"type":"string","description":"The operator of the condition"},"attribute_name":{"type":"string","description":"The attribute name of the condition"},"value":{"type":"string","description":"The value of the condition"},"extension_attributes":{"$ref":"#/definitions/sales-rule-data-condition-extension-interface"}},"required":["condition_type","operator","value"]},"sales-rule-data-condition-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\SalesRule\\Api\\Data\\ConditionInterface"},"sales-rule-data-rule-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\SalesRule\\Api\\Data\\RuleInterface","properties":{"reward_points_delta":{"type":"integer"}}},"sales-rule-data-rule-search-result-interface":{"type":"object","description":"","properties":{"items":{"type":"array","description":"Rules.","items":{"$ref":"#/definitions/sales-rule-data-rule-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-rule-data-coupon-interface":{"type":"object","description":"Interface CouponInterface","properties":{"coupon_id":{"type":"integer","description":"Coupon id"},"rule_id":{"type":"integer","description":"The id of the rule associated with the coupon"},"code":{"type":"string","description":"Coupon code"},"usage_limit":{"type":"integer","description":"Usage limit"},"usage_per_customer":{"type":"integer","description":"Usage limit per customer"},"times_used":{"type":"integer","description":"The number of times the coupon has been used"},"expiration_date":{"type":"string","description":"Expiration date"},"is_primary":{"type":"boolean","description":"The coupon is primary coupon for the rule that it's associated with"},"created_at":{"type":"string","description":"When the coupon is created"},"type":{"type":"integer","description":"Of coupon"},"extension_attributes":{"$ref":"#/definitions/sales-rule-data-coupon-extension-interface"}},"required":["rule_id","times_used","is_primary"]},"sales-rule-data-coupon-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\SalesRule\\Api\\Data\\CouponInterface"},"sales-rule-data-coupon-search-result-interface":{"type":"object","description":"","properties":{"items":{"type":"array","description":"Rules.","items":{"$ref":"#/definitions/sales-rule-data-coupon-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"sales-rule-data-coupon-generation-spec-interface":{"type":"object","description":"CouponGenerationSpecInterface","properties":{"rule_id":{"type":"integer","description":"The id of the rule associated with the coupon"},"format":{"type":"string","description":"Format of generated coupon code"},"quantity":{"type":"integer","description":"Of coupons to generate"},"length":{"type":"integer","description":"Length of coupon code"},"prefix":{"type":"string","description":"The prefix"},"suffix":{"type":"string","description":"The suffix"},"delimiter_at_every":{"type":"integer","description":"The spacing where the delimiter should exist"},"delimiter":{"type":"string","description":"The delimiter"},"extension_attributes":{"$ref":"#/definitions/sales-rule-data-coupon-generation-spec-extension-interface"}},"required":["rule_id","format","quantity","length"]},"sales-rule-data-coupon-generation-spec-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\SalesRule\\Api\\Data\\CouponGenerationSpecInterface"},"sales-rule-data-coupon-mass-delete-result-interface":{"type":"object","description":"Coupon mass delete results interface.","properties":{"failed_items":{"type":"array","description":"List of failed items.","items":{"type":"string"}},"missing_items":{"type":"array","description":"List of missing items.","items":{"type":"string"}}},"required":["failed_items","missing_items"]},"rma-data-track-interface":{"type":"object","description":"Interface TrackInterface","properties":{"entity_id":{"type":"integer","description":"Entity id"},"rma_entity_id":{"type":"integer","description":"Rma entity id"},"track_number":{"type":"string","description":"Track number"},"carrier_title":{"type":"string","description":"Carrier title"},"carrier_code":{"type":"string","description":"Carrier code"},"extension_attributes":{"$ref":"#/definitions/rma-data-track-extension-interface"}},"required":["entity_id","rma_entity_id","track_number","carrier_title","carrier_code"]},"rma-data-track-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Rma\\Api\\Data\\TrackInterface"},"rma-data-track-search-result-interface":{"type":"object","description":"Interface TrackSearchResultInterface","properties":{"items":{"type":"array","description":"Rma list","items":{"$ref":"#/definitions/rma-data-track-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"rma-data-rma-interface":{"type":"object","description":"Interface RmaInterface","properties":{"increment_id":{"type":"string","description":"Entity_id"},"entity_id":{"type":"integer","description":"Entity_id"},"order_id":{"type":"integer","description":"Order_id"},"order_increment_id":{"type":"string","description":"Order_increment_id"},"store_id":{"type":"integer","description":"Store_id"},"customer_id":{"type":"integer","description":"Customer_id"},"date_requested":{"type":"string","description":"Date_requested"},"customer_custom_email":{"type":"string","description":"Customer_custom_email"},"items":{"type":"array","description":"Items","items":{"$ref":"#/definitions/rma-data-item-interface"}},"status":{"type":"string","description":"Status"},"comments":{"type":"array","description":"Comments list","items":{"$ref":"#/definitions/rma-data-comment-interface"}},"tracks":{"type":"array","description":"Tracks list","items":{"$ref":"#/definitions/rma-data-track-interface"}},"extension_attributes":{"$ref":"#/definitions/rma-data-rma-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["increment_id","entity_id","order_id","order_increment_id","store_id","customer_id","date_requested","customer_custom_email","items","status","comments","tracks"]},"rma-data-item-interface":{"type":"object","description":"Interface CategoryInterface","properties":{"entity_id":{"type":"integer","description":"Id"},"rma_entity_id":{"type":"integer","description":"RMA id"},"order_item_id":{"type":"integer","description":"Order_item_id"},"qty_requested":{"type":"integer","description":"Qty_requested"},"qty_authorized":{"type":"integer","description":"Qty_authorized"},"qty_approved":{"type":"integer","description":"Qty_approved"},"qty_returned":{"type":"integer","description":"Qty_returned"},"reason":{"type":"string","description":"Reason"},"condition":{"type":"string","description":"Condition"},"resolution":{"type":"string","description":"Resolution"},"status":{"type":"string","description":"Status"},"extension_attributes":{"$ref":"#/definitions/rma-data-item-extension-interface"}},"required":["entity_id","rma_entity_id","order_item_id","qty_requested","qty_authorized","qty_approved","qty_returned","reason","condition","resolution","status"]},"rma-data-item-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Rma\\Api\\Data\\ItemInterface"},"rma-data-comment-interface":{"type":"object","description":"Interface CommentInterface","properties":{"comment":{"type":"string","description":"Comment"},"rma_entity_id":{"type":"integer","description":"Rma Id"},"created_at":{"type":"string","description":"Created_at"},"entity_id":{"type":"integer","description":"Entity_id"},"customer_notified":{"type":"boolean","description":"Is_customer_notified"},"visible_on_front":{"type":"boolean","description":"Is_visible_on_front"},"status":{"type":"string","description":"Status"},"admin":{"type":"boolean","description":"Is_admin"},"extension_attributes":{"$ref":"#/definitions/rma-data-comment-extension-interface"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["comment","rma_entity_id","created_at","entity_id","customer_notified","visible_on_front","status","admin"]},"rma-data-comment-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Rma\\Api\\Data\\CommentInterface"},"rma-data-rma-extension-interface":{"type":"object","description":"ExtensionInterface class for @see \\Magento\\Rma\\Api\\Data\\RmaInterface"},"rma-data-comment-search-result-interface":{"type":"object","description":"Interface CommentSearchResultInterface","properties":{"items":{"type":"array","description":"Rma Status History list","items":{"$ref":"#/definitions/rma-data-comment-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"rma-data-rma-search-result-interface":{"type":"object","description":"Interface RmaSearchResultInterface","properties":{"items":{"type":"array","description":"Rma list","items":{"$ref":"#/definitions/rma-data-rma-interface"}},"search_criteria":{"$ref":"#/definitions/framework-search-criteria-interface"},"total_count":{"type":"integer","description":"Total count."}},"required":["items","search_criteria","total_count"]},"framework-metadata-object-interface":{"type":"object","description":"Provides metadata about an attribute.","properties":{"attribute_code":{"type":"string","description":"Code of the attribute."}},"required":["attribute_code"]},"test-module1-v1-entity-item":{"type":"object","description":"","properties":{"item_id":{"type":"integer"},"name":{"type":"string"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["item_id","name"]},"test-module1-v2-entity-item":{"type":"object","description":"","properties":{"id":{"type":"integer"},"name":{"type":"string"},"price":{"type":"string"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["id","name","price"]},"test-module2-v1-entity-item":{"type":"object","description":"","properties":{"id":{"type":"integer"},"name":{"type":"string"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["id","name"]},"test-module3-v1-entity-parameter":{"type":"object","description":"","properties":{"name":{"type":"string","description":"$name"},"value":{"type":"string","description":"$value"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["name","value"]},"test-module3-v1-entity-wrapped-error-parameter":{"type":"object","description":"","properties":{"field_name":{"type":"string","description":"$name"},"value":{"type":"string","description":"$value"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["field_name","value"]},"test-module4-v1-entity-data-object-response":{"type":"object","description":"","properties":{"entity_id":{"type":"integer"},"name":{"type":"string"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["entity_id","name"]},"test-module4-v1-entity-data-object-request":{"type":"object","description":"","properties":{"name":{"type":"string"},"entity_id":{"type":"integer"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["name"]},"test-module4-v1-entity-nested-data-object-request":{"type":"object","description":"","properties":{"details":{"$ref":"#/definitions/test-module4-v1-entity-data-object-request"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["details"]},"test-module4-v1-entity-extensible-request-interface":{"type":"object","description":"","properties":{"name":{"type":"string"},"entity_id":{"type":"integer"}},"required":["name"]},"test-module5-v1-entity-all-soap-and-rest":{"type":"object","description":"Some Data Object short description. Data Object long multi line description.","properties":{"entity_id":{"type":"integer","description":"Item ID"},"name":{"type":"string","description":"Item name"},"enabled":{"type":"boolean","description":"If entity is enabled"},"orders":{"type":"boolean","description":"If current entity has a property defined"},"custom_attributes":{"type":"array","description":"Custom attributes values.","items":{"$ref":"#/definitions/framework-attribute-interface"}}},"required":["entity_id","enabled","orders"]},"test-module5-v2-entity-all-soap-and-rest":{"type":"object","description":"Some Data Object short description. Data Object long multi line description.","properties":{"price":{"type":"integer"}},"required":["price"]},"test-module-ms-cdata-item-interface":{"type":"object","description":"","properties":{"item_id":{"type":"integer"},"name":{"type":"string"}},"required":["item_id","name"]}}} \ No newline at end of file diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/definition.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/definition.mustache new file mode 100644 index 000000000..e61212219 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/definition.mustache @@ -0,0 +1,14 @@ + + + + + + {{> field2 }} + {{> array1 }} + + \ No newline at end of file diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/operation.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/operation.mustache new file mode 100644 index 000000000..5114f233a --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/operation.mustache @@ -0,0 +1,16 @@ + + + + + + application/json + {{> field }} + {{> param }} + {{> array }} + + \ No newline at end of file diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array1.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array1.mustache new file mode 100644 index 000000000..3669c78d0 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array1.mustache @@ -0,0 +1,12 @@ +{{! +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{# arrays1 }} + + {{> value }} + {{> arrays2 }} + +{{/ arrays1 }} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array2.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array2.mustache new file mode 100644 index 000000000..072b430fb --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array2.mustache @@ -0,0 +1,12 @@ +{{! +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{# arrays2 }} + + {{> value }} + {{> arrays3 }} + +{{/ arrays2 }} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array3.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array3.mustache new file mode 100644 index 000000000..401dbbcbd --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/array3.mustache @@ -0,0 +1,12 @@ +{{! +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{! No array is nested more than 2 level in Magento2 swagger spec. }} +{{# arrays3 }} + + {{> value }} + +{{/ arrays3 }} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/field.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/field.mustache new file mode 100644 index 000000000..29a822d05 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/field.mustache @@ -0,0 +1,9 @@ +{{! +/** + * Copyright ? Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{# fields }} +{{ fieldType }} +{{/ fields }} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/field2.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/field2.mustache new file mode 100644 index 000000000..bf4f6c2a5 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/field2.mustache @@ -0,0 +1,9 @@ +{{! +/** + * Copyright ? Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{# fields }} +{{ fieldType }} +{{/ fields }} diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/param.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/param.mustache new file mode 100644 index 000000000..be5f4a3ef --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/param.mustache @@ -0,0 +1,9 @@ +{{! +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{# params }} +{{ paramType }} +{{/ params }} \ No newline at end of file diff --git a/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/value.mustache b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/value.mustache new file mode 100644 index 000000000..def0c03ff --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Util/MetadataGenerator/Swagger/views/partials/value.mustache @@ -0,0 +1,9 @@ +{{! +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +}} +{{# values }} +{{ value }} +{{/ values }} diff --git a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php index 2108627aa..94e1117ac 100644 --- a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php @@ -18,6 +18,7 @@ class TestGenerator { const REQUIRED_ENTITY_REFERENCE = 'createDataKey'; + const TEST_SCOPE = 'Test'; const GENERATED_DIR = '_generated'; /** @@ -151,7 +152,7 @@ public function createAllCestFiles($runConfig = null) private function assembleCestPhp($cestObject) { $usePhp = $this->generateUseStatementsPhp(); - $classAnnotationsPhp = $this->generateClassAnnotationsPhp($cestObject->getAnnotations()); + $classAnnotationsPhp = $this->generateAnnotationsPhp($cestObject->getAnnotations(), "Cest"); $className = $cestObject->getName(); $className = str_replace(' ', '', $className); try { @@ -213,6 +214,7 @@ private function generateUseStatementsPhp() $useStatementsPhp .= "use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;\n"; $useStatementsPhp .= "use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler;\n"; $useStatementsPhp .= "use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject;\n"; + $useStatementsPhp .= "use \Codeception\Util\Locator;\n"; $allureStatements = [ "Yandex\Allure\Adapter\Annotation\Features;", @@ -233,17 +235,22 @@ private function generateUseStatementsPhp() } /** - * Creates a PHP string for the Class Annotations block if the Cest file contains an block, outside - * of the blocks. - * - * @param array $classAnnotationsObject + * Generates Annotations PHP for given object, using given scope to determine indentation and additional output. + * @param array $annotationsObject + * @param string $scope * @return string */ - private function generateClassAnnotationsPhp($classAnnotationsObject) + private function generateAnnotationsPhp($annotationsObject, $scope) { - $classAnnotationsPhp = "/**\n"; + if ($scope == self::TEST_SCOPE) { + $indent = "\t"; + } else { + $indent = ""; + } + + $annotationsPhp = "{$indent}/**\n"; - foreach ($classAnnotationsObject as $annotationType => $annotationName) { + foreach ($annotationsObject as $annotationType => $annotationName) { if ($annotationType == "features") { $features = ""; @@ -255,7 +262,7 @@ private function generateClassAnnotationsPhp($classAnnotationsObject) } } - $classAnnotationsPhp .= sprintf(" * @Features({%s})\n", $features); + $annotationsPhp .= sprintf("{$indent} * @Features({%s})\n", $features); } if ($annotationType == "stories") { @@ -269,45 +276,55 @@ private function generateClassAnnotationsPhp($classAnnotationsObject) } } - $classAnnotationsPhp .= sprintf(" * @Stories({%s})\n", $stories); + $annotationsPhp .= sprintf("{$indent} * @Stories({%s})\n", $stories); } if ($annotationType == "title") { - $classAnnotationsPhp .= sprintf( - " * @Title(\"%s\")\n", - ucwords($annotationType), - $annotationName[0] - ); + $annotationsPhp .= sprintf("{$indent} * @Title(\"%s\")\n", $annotationName[0]); } if ($annotationType == "description") { - $classAnnotationsPhp .= sprintf(" * @Description(\"%s\")\n", $annotationName[0]); + $annotationsPhp .= sprintf("{$indent} * @Description(\"%s\")\n", $annotationName[0]); } if ($annotationType == "severity") { - $classAnnotationsPhp .= sprintf(" * @Severity(level = SeverityLevel::%s)\n", $annotationName[0]); + $annotationsPhp .= sprintf("{$indent} * @Severity(level = SeverityLevel::%s)\n", $annotationName[0]); } if ($annotationType == "testCaseId") { - $classAnnotationsPhp .= sprintf(" * TestCaseId(\"%s\")\n", $annotationName[0]); + $annotationsPhp .= sprintf("{$indent} * @TestCaseId(\"%s\")\n", $annotationName[0]); + } + + if ($annotationType == "useCaseId") { + $annotationsPhp .= sprintf("{$indent} * @UseCaseId(\"%s\")\n", $annotationName[0]); } if ($annotationType == "group") { foreach ($annotationName as $group) { - $classAnnotationsPhp .= sprintf(" * @group %s\n", $group); + $annotationsPhp .= sprintf("{$indent} * @group %s\n", $group); } } if ($annotationType == "env") { foreach ($annotationName as $env) { - $classAnnotationsPhp .= sprintf(" * @env %s\n", $env); + $annotationsPhp .= sprintf("{$indent} * @env %s\n", $env); } } } - $classAnnotationsPhp .= " */\n"; + if ($scope == self::TEST_SCOPE) { + $annotationsPhp .= sprintf( + "{$indent} * @Parameter(name = \"%s\", value=\"$%s\")\n", + "AcceptanceTester", + "I" + ); + $annotationsPhp .= sprintf("{$indent} * @param %s $%s\n", "AcceptanceTester", "I"); + $annotationsPhp .= "{$indent} * @return void\n"; + } + + $annotationsPhp .= "{$indent} */\n"; - return $classAnnotationsPhp; + return $annotationsPhp; } /** @@ -352,6 +369,12 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) $dependentSelector = null; $visible = null; + $assertExpected = null; + $assertActual = null; + $assertMessage = null; + $assertIsStrict = null; + $assertDelta = null; + if (isset($customActionAttributes['returnVariable'])) { $returnVariable = $customActionAttributes['returnVariable']; } @@ -366,11 +389,31 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) } elseif (isset($customActionAttributes['url'])) { $input = $this->addUniquenessFunctionCall($customActionAttributes['url']); } + if (isset($customActionAttributes['expected'])) { + $assertExpected = $this->resolveValueByType( + $customActionAttributes['expected'], + isset($customActionAttributes['expectedType']) ? $customActionAttributes['expectedType'] : null + ); + } + if (isset($customActionAttributes['actual'])) { + $assertActual = $this->resolveValueByType( + $customActionAttributes['actual'], + isset($customActionAttributes['actualType']) ? $customActionAttributes['actualType'] : null + ); + } + if (isset($customActionAttributes['message'])) { + $assertMessage = $this->addUniquenessFunctionCall($customActionAttributes['message']); + } + if (isset($customActionAttributes['delta'])) { + $assertDelta = $this->resolveValueByType($customActionAttributes['delta'], "float"); + } + if (isset($customActionAttributes['strict'])) { + $assertIsStrict = $this->resolveValueByType($customActionAttributes['strict'], "bool"); + } if (isset($customActionAttributes['time'])) { $time = $customActionAttributes['time']; } - if (isset($customActionAttributes['timeout'])) { $time = $customActionAttributes['timeout']; } @@ -392,14 +435,17 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) $selector = $customActionAttributes['selectorArray']; } elseif (isset($customActionAttributes['selector'])) { $selector = $this->addUniquenessFunctionCall($customActionAttributes['selector']); + $selector = $this->resolveLocatorFunctionInAttribute($selector); } if (isset($customActionAttributes['selector1'])) { $selector1 = $this->addUniquenessFunctionCall($customActionAttributes['selector1']); + $selector1 = $this->resolveLocatorFunctionInAttribute($selector1); } if (isset($customActionAttributes['selector2'])) { $selector2 = $this->addUniquenessFunctionCall($customActionAttributes['selector2']); + $selector2 = $this->resolveLocatorFunctionInAttribute($selector2); } if (isset($customActionAttributes['x'])) { @@ -451,7 +497,7 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) } if (isset($customActionAttributes['dependentSelector'])) { - $dependentSelector = $this->wrapWithDoubleQuotes($customActionAttributes['dependentSelector']); + $dependentSelector = $this->addUniquenessFunctionCall($customActionAttributes['dependentSelector']); } if (isset($customActionAttributes['visible'])) { @@ -548,40 +594,48 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) } break; case "updateData": - $entity = $customActionAttributes['entity']; - $originalEntity = null; - if (isset($customActionAttributes['createDataKey'])) { - $originalEntity = $customActionAttributes['createDataKey']; - } - $key = $steps->getMergeKey(); + $key = $customActionAttributes['createDataKey']; + $updateEntity = $customActionAttributes['entity']; + //Add an informative statement to help the user debug test runs $testSteps .= sprintf( - "\t\t$%s->amGoingTo(\"update entity that has the mergeKey: %s\");\n", + "\t\t$%s->amGoingTo(\"update entity that has the createdDataKey: %s\");\n", $actor, $key ); - //Get Entity from Static data. - $testSteps .= sprintf( - "\t\t$%s = DataObjectHandler::getInstance()->getObject(\"%s\");\n", - $entity, - $entity - ); + + //HookObject End-Product needs to be created in the Class/Cest scope, + //otherwise create them in the Test scope. + //Determine if there are required-entities and create array of required-entities for merging. + $requiredEntities = []; + $requiredEntityObjects = []; + foreach ($customActionAttributes as $customAttribute) { + if (is_array($customAttribute) && $customAttribute['nodeName'] = 'required-entity') { + if ($hookObject) { + $requiredEntities [] = "\$this->" . $customAttribute[self::REQUIRED_ENTITY_REFERENCE] . + "->getName() => " . "\$this->" . $customAttribute[self::REQUIRED_ENTITY_REFERENCE] . + "->getType()"; + $requiredEntityObjects [] = '$this->' . $customAttribute + [self::REQUIRED_ENTITY_REFERENCE]; + } else { + $requiredEntities [] = "\$" . $customAttribute[self::REQUIRED_ENTITY_REFERENCE] + . "->getName() => " . "\$" . $customAttribute[self::REQUIRED_ENTITY_REFERENCE] . + "->getType()"; + $requiredEntityObjects [] = '$' . $customAttribute[self::REQUIRED_ENTITY_REFERENCE]; + } + } + } if ($hookObject) { - $updateEntityFunctionCall = sprintf("\t\t\$this->%s->updateEntity(", $key); - $dataPersistenceHandlerFunctionCall = sprintf( - "\t\t\$this->%s = new DataPersistenceHandler($%s, [\$this->%s]);\n", - $key, - $entity, - $originalEntity - ); + $updateEntityFunctionCall = sprintf("\t\t\$this->%s->updateEntity(\"%s\"", $key, $updateEntity); } else { - $updateEntityFunctionCall = sprintf("\t\t\$%s->updateEntity(", $key); - $dataPersistenceHandlerFunctionCall = sprintf( - "\t\t$%s = new DataPersistenceHandler($%s, [$%s]);\n", - $key, - $entity, - $originalEntity + $updateEntityFunctionCall = sprintf("\t\t\$%s->updateEntity(\"%s\"", $key, $updateEntity); + } + + if (!empty($requiredEntities)) { + $updateEntityFunctionCall .= sprintf( + ", [%s]", + implode(', ', $requiredEntityObjects) ); } @@ -591,7 +645,6 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) $updateEntityFunctionCall .= ");\n"; } - $testSteps .= $dataPersistenceHandlerFunctionCall; $testSteps .= $updateEntityFunctionCall; break; case "getData": @@ -883,6 +936,71 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) case "conditionalClick": $testSteps .= $this->wrapFunctionCall($actor, $actionName, $selector, $dependentSelector, $visible); break; + case "assertEquals": + case "assertGreaterOrEquals": + case "assertGreaterThan": + case "assertGreaterThanOrEqual": + case "assertInternalType": + case "assertLessOrEquals": + case "assertLessThan": + case "assertLessThanOrEqual": + case "assertNotEquals": + case "assertInstanceOf": + case "assertNotInstanceOf": + case "assertNotRegExp": + case "assertNotSame": + case "assertRegExp": + case "assertSame": + case "assertStringStartsNotWith": + case "assertStringStartsWith": + case "assertArrayHasKey": + case "assertArrayNotHasKey": + case "assertCount": + case "assertContains": + case "assertNotContains": + case "expectException": + $testSteps .= $this->wrapFunctionCall( + $actor, + $actionName, + $assertExpected, + $assertActual, + $assertMessage, + $assertDelta + ); + break; + case "assertEmpty": + case "assertFalse": + case "assertFileExists": + case "assertFileNotExists": + case "assertIsEmpty": + case "assertNotEmpty": + case "assertNotNull": + case "assertNull": + case "assertTrue": + $testSteps .= $this->wrapFunctionCall( + $actor, + $actionName, + $assertActual, + $assertMessage + ); + break; + case "assertArraySubset": + $testSteps .= $this->wrapFunctionCall( + $actor, + $actionName, + $assertExpected, + $assertActual, + $assertIsStrict, + $assertMessage + ); + break; + case "fail": + $testSteps .= $this->wrapFunctionCall( + $actor, + $actionName, + $assertMessage + ); + break; default: if ($returnVariable) { $testSteps .= $this->wrapFunctionCallWithReturnValue( @@ -902,6 +1020,20 @@ private function generateStepsPhp($stepsObject, $stepsData, $hookObject = false) return $testSteps; } + /** + * Resolves Locator:: in given $attribute if it is found. + * @param string $attribute + * @return string + */ + private function resolveLocatorFunctionInAttribute($attribute) + { + if (strpos($attribute, "Locator::") !== false) { + $attribute = $this->stripWrappedQuotes($attribute); + $attribute = $this->wrapFunctionArgsWithQuotes("/Locator::[\w]+\(([\s\S]+)\)/", $attribute); + } + return $attribute; + } + /** * Resolves replacement of $input$ and $$input$$ in given function, recursing and replacing individual arguments * Also determines if each argument requires any quote replacement. @@ -976,32 +1108,49 @@ private function replaceMatchesIntoArg($matches, &$outputArg, $delimiter) */ private function processQuoteBreaks($match, $argument, $replacement) { - $outputArg = $argument; - $beforeIndex = strpos($outputArg, $match) - 1; - $afterIndex = $beforeIndex + strlen($match) + 1; - - $quoteBefore = false; - // Determine if there is a " before/after the $match, and if there is only one " before/after match. - if ($beforeIndex == 0 - || ($argument[$beforeIndex] == '"' && substr_count($argument, '"', 0, $beforeIndex) < 1)) { - $quoteBefore = true; - } - $quoteAfter = $argument[$afterIndex] == '"' && substr_count($argument, '"', $afterIndex+1) < 1; + $outputArg = str_replace($match, '" . ' . $replacement . ' . "', $argument); - //Remove quotes at either end of argument if they aren't necessary. Add double-quote concatenation if needed. - if ($quoteBefore) { - $outputArg = substr($outputArg, 0, $beforeIndex) . substr($outputArg, $beforeIndex+1); - $afterIndex--; - } else { - $replacement = '" . ' . $replacement; + //Sanitize string of any unnecessary '"" .' and '. ""'. + //Regex means: Search for '"" . ' but not '\"" . ' and ' . ""'. + //Matches on '"" . ' and ' . ""', but not on '\"" . ' and ' . "\"'. + $outputArg = preg_replace('/(?(?addUniquenessToParamArray($argument) . "]"; + } elseif (is_numeric($argument)) { + $replacement = $argument; + } else { + $replacement = $this->addUniquenessFunctionCall($argument); + } + + //Replace only first occurrence of argument with "argument" + $pos = strpos($output, $argument); + $output = substr_replace($output, $replacement, $pos, strlen($argument)); } - $outputArg = str_replace($match, $replacement, $outputArg); - return $outputArg; + + return $output; } /** @@ -1020,6 +1169,7 @@ private function stripAndSplitReference($reference, $delimiter) * Creates a PHP string for the _before/_after methods if the Test contains an or block. * @param array $hookObjects * @return string + * @throws TestReferenceException */ private function generateHooksPhp($hookObjects) { @@ -1077,97 +1227,12 @@ private function generateHooksPhp($hookObjects) return $hooks; } - /** - * Creates a PHP string for the Test Annotations block if the Test contains an block. - * - * @param array $testAnnotationsObject - * @return string - */ - private function generateTestAnnotationsPhp($testAnnotationsObject) - { - $testAnnotationsPhp = "\t/**\n"; - - foreach ($testAnnotationsObject as $annotationType => $annotationName) { - if ($annotationType == "features") { - $features = ""; - - foreach ($annotationName as $name) { - $features .= sprintf("\"%s\"", $name); - - if (next($annotationName)) { - $features .= ", "; - } - } - - $testAnnotationsPhp .= sprintf("\t * @Features({%s})\n", $features); - } - - if ($annotationType == "stories") { - $stories = ""; - - foreach ($annotationName as $name) { - $stories .= sprintf("\"%s\"", $name); - - if (next($annotationName)) { - $stories .= ", "; - } - } - - $testAnnotationsPhp .= sprintf("\t * @Stories({%s})\n", $stories); - } - - if ($annotationType == "title") { - $testAnnotationsPhp .= sprintf("\t * @Title(\"%s\")\n", $annotationName[0]); - } - - if ($annotationType == "description") { - $testAnnotationsPhp .= sprintf("\t * @Description(\"%s\")\n", $annotationName[0]); - } - - if ($annotationType == "severity") { - $testAnnotationsPhp .= sprintf( - "\t * @Severity(level = SeverityLevel::%s)\n", - $annotationName[0] - ); - } - - if ($annotationType == "testCaseId") { - $testAnnotationsPhp .= sprintf("\t * @TestCaseId(\"%s\")\n", $annotationName[0]); - } - } - - $testAnnotationsPhp .= sprintf( - "\t * @Parameter(name = \"%s\", value=\"$%s\")\n", - "AcceptanceTester", - "I" - ); - - foreach ($testAnnotationsObject as $annotationType => $annotationName) { - if ($annotationType == "group") { - foreach ($annotationName as $name) { - $testAnnotationsPhp .= sprintf("\t * @group %s\n", $name); - } - } - - if ($annotationType == "env") { - foreach ($annotationName as $env) { - $testAnnotationsPhp .= sprintf("\t * @env %s\n", $env); - } - } - } - - $testAnnotationsPhp .= sprintf("\t * @param %s $%s\n", "AcceptanceTester", "I"); - $testAnnotationsPhp .= "\t * @return void\n"; - $testAnnotationsPhp .= "\t */\n"; - - return $testAnnotationsPhp; - } - /** * Creates a PHP string based on a block. * Concatenates the Test Annotations PHP and Test PHP for a single Test. * @param array $testsObject * @return string + * @throws TestReferenceException */ private function generateTestsPhp($testsObject) { @@ -1176,7 +1241,7 @@ private function generateTestsPhp($testsObject) foreach ($testsObject as $test) { $testName = $test->getName(); $testName = str_replace(' ', '', $testName); - $testAnnotations = $this->generateTestAnnotationsPhp($test->getAnnotations()); + $testAnnotations = $this->generateAnnotationsPhp($test->getAnnotations(), "Test"); $dependencies = 'AcceptanceTester $I'; try { $steps = $this->generateStepsPhp($test->getOrderedActions(), $test->getCustomData()); @@ -1306,7 +1371,7 @@ private function stripWrappedQuotes($input) */ private function addDollarSign($input) { - return sprintf("$%s", $input); + return sprintf("$%s", ltrim($this->stripQuotes($input), '$')); } // @codingStandardsIgnoreStart @@ -1380,4 +1445,74 @@ private function validateParameterArray($paramArray) throw new TestReferenceException("parameterArray must begin with `[` and end with `]"); } } + + /** + * Resolve value based on type. + * + * @param string $value + * @param string $type + * @return string + */ + private function resolveValueByType($value, $type) + { + if (null === $value) { + return null; + } + if (null === $type) { + $type = 'const'; + } + if ($type == "string") { + return $this->addUniquenessFunctionCall($value); + } elseif ($type == "bool") { + return $this->toBoolean($value) ? "true" : "false"; + } elseif ($type == "int" || $type == "float") { + return $this->toNumber($value); + } elseif ($type == "array") { + $this->validateParameterArray($value); + return "[" . $this->addUniquenessToParamArray($value) . "]"; + } elseif ($type == "variable") { + return $this->addDollarSign($value); + } else { + return $value; + } + } + + /** + * Convert input string to boolean equivalent. + * + * @param string $inStr + * @return bool|null + */ + private function toBoolean($inStr) + { + return boolval($this->stripQuotes($inStr)); + } + + /** + * Convert input string to number equivalent. + * + * @param string $inStr + * @return int|float|null + */ + private function toNumber($inStr) + { + $outStr = $this->stripQuotes($inStr); + if (strpos($outStr, localeconv()['decimal_point']) === false) { + return intval($outStr); + } else { + return floatval($outStr); + } + } + + /** + * Strip single or double quotes from begin and end of input string. + * + * @param string $inStr + * @return string + */ + private function stripQuotes($inStr) + { + $unquoted = preg_replace('/^(\'(.*)\'|"(.*)")$/', '$2$3', $inStr); + return $unquoted; + } }