diff --git a/behat_suites.yml b/behat_suites.yml index a7cf1ecd..8524a1ad 100644 --- a/behat_suites.yml +++ b/behat_suites.yml @@ -2,7 +2,7 @@ behat: suites: examples: paths: - - '%paths.base%/vendor/ezsystems/behatbundle/features/' + - '%paths.base%/vendor/ezsystems/behatbundle/features/examples' contexts: - EzSystems\Behat\API\Context\TestContext: userService: '@ezpublish.api.service.user' @@ -10,14 +10,15 @@ behat: - EzSystems\Behat\API\Context\ObjectStateContext: objectStateService: '@ezpublish.api.service.object_state' - EzSystems\Behat\API\Context\ContentContext: - contentFacade: '@ezbehatbundle.api.facade.contentfacade' + contentFacade: '@EzSystems\Behat\API\Facade\ContentFacade' + argumentParser: '@EzSystems\Behat\Core\Behat\ArgumentParser' - EzSystems\Behat\API\Context\ContentTypeContext: - contentTypeFacade: '@ezbehatbundle.api.facade.contenttypefacade' + contentTypeFacade: '@EzSystems\Behat\API\Facade\ContentTypeFacade' - EzSystems\Behat\API\Context\UserContext: - userFacade: '@ezbehatbundle.api.facade.userfacade' + userFacade: '@EzSystems\Behat\API\Facade\UserFacade' - EzSystems\Behat\API\Context\RoleContext: - roleFacade: '@ezbehatbundle.api.facade.rolefacade' + roleFacade: '@EzSystems\Behat\API\Facade\RoleFacade' - EzSystems\Behat\API\Context\LanguageContext: - languageFacade: '@ezbehatbundle.api.facade.languagefacade' + languageFacade: '@EzSystems\Behat\API\Facade\LanguageFacade' - EzSystems\Behat\Core\Context\ConfigurationContext: - projectDir: '%paths.base%' \ No newline at end of file + projectDir: '%paths.base%' diff --git a/composer.json b/composer.json index 1d34f993..30169232 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,10 @@ "ezsystems/ezpublish-kernel": "^8.0@dev", "fzaninotto/faker": "^1.8", "behat/behat": "^3.5", + "behat/mink": "^1.7", + "behat/mink-selenium2-driver": "^1.3", + "behat/symfony2-extension": "^2.1", + "behat/mink-extension": "^2.3", "symfony/property-access": "^4.3", "symfony/yaml": "^4.3", "symfony/config": "^4.3", diff --git a/features/content_creation.feature b/features/content_creation.feature deleted file mode 100644 index 6f815e52..00000000 --- a/features/content_creation.feature +++ /dev/null @@ -1,36 +0,0 @@ -Feature: Example scenarios showing how to use steps involving Languages, Content Types and Content Items - - @admin - Scenario Outline: Create a language, Content Type and Content Items - Given Language "Polski" with code "pol-PL" exists - And I create a "" Content Type in "Content" with "" identifier - | Field Type | Name | Identifier | Required | Searchable | Translatable | - | Text line | Name | name | yes | yes | yes | - | | TestedField | testedfield | yes | no | yes | - And I create "Folder" Content items in root in "pol-PL" - | name | short_name | - | | | - And I create 50 "" Content items in "" in "pol-PL" - - Examples: - | contentTypeName | contentTypeIdentifier | fieldType | - | RichText CT | RichTextCT | Rich text | - | URL CT | URLCT | URL | - | Email CT | EmailCT | Email address | - | Textline CT | TextlineCT | Text line | - | ISBN CT | IsbnCT | ISBN | - | Authors CT | AuthorsCT | Authors | - | Text block CT | TextBlockCT | Text block | - | Checkbox CT | CheckboxCT | Checkbox | - | Country CT | CountryCT | Country | - | Date CT | DateCT | Date | - | Time CT | TimeCT | Time | - | Float CT | FloatCT | Float | - | Integer CT | Integer | Integer | - | Map location CT | MapLocationCT | Map location | - | Date and time CT | DateAndTimeCT | Date and time | - | Content relation CT | ContentRelationCT | Content relation (single) | - | Content relations CT | ContentRelationsCT | Content relations (multiple) | - | Image CT | ImageCT | Image | - | File CT | FileCT | File | - | Media CT | MediaCT | Media | diff --git a/features/configuration.feature b/features/examples/configuration.feature similarity index 100% rename from features/configuration.feature rename to features/examples/configuration.feature diff --git a/features/examples/content.feature b/features/examples/content.feature new file mode 100644 index 00000000..083ed3f7 --- /dev/null +++ b/features/examples/content.feature @@ -0,0 +1,76 @@ +Feature: Example scenarios showing how to use steps involving Languages, Content Types and Content Items + + @admin + Scenario Outline: Create a language, Content Type and Content Items + Given Language "Polski" with code "pol-PL" exists + And I create a "" Content Type in "Content" with "" identifier + | Field Type | Name | Identifier | Required | Searchable | Translatable | + | Text line | Name | name | yes | yes | yes | + | | TestedField | testedfield | yes | no | yes | + And I create "Folder" Content items in root in "pol-PL" + | name | short_name | + | | | + And I create 50 "" Content items in "" in "pol-PL" + + Examples: + | contentTypeName | contentTypeIdentifier | fieldType | + | RichText CT | RichTextCT | Rich text | + | URL CT | URLCT | URL | + | Email CT | EmailCT | Email address | + | Textline CT | TextlineCT | Text line | + | ISBN CT | IsbnCT | ISBN | + | Authors CT | AuthorsCT | Authors | + | Text block CT | TextBlockCT | Text block | + | Checkbox CT | CheckboxCT | Checkbox | + | Country CT | CountryCT | Country | + | Date CT | DateCT | Date | + | Time CT | TimeCT | Time | + | Float CT | FloatCT | Float | + | Integer CT | Integer | Integer | + | Map location CT | MapLocationCT | Map location | + | Date and time CT | DateAndTimeCT | Date and time | + | Content relation CT | ContentRelationCT | Content relation (single) | + | Content relations CT | ContentRelationsCT | Content relations (multiple) | + | Image CT | ImageCT | Image | + | File CT | FileCT | File | + | Media CT | MediaCT | Media | + + @admin + Scenario Outline: Create a Content item and edit specified field + Given I create a "" Content Type in "Content" with "" identifier + | Field Type | Name | Identifier | Required | Searchable | Translatable | + | Text line | Name | name | yes | yes | yes | + | | TestedField | testedfield | yes | no | yes | + And I create Content items in root in "eng-GB" + | name | + | | + And I create "Folder" Content items in root in "eng-GB" + | name | short_name | + | RelationFolder1 | RelationFolder1 | + | RelationFolder2 | RelationFolder2 | + When I edit "" Content item in "eng-GB" + | testedfield | + | | + + Examples: + | contentTypeName | contentTypeIdentifier | fieldType | valueToSet | + | RichText CT2 | RichTextCT2 | Rich text | EditedField | + | URL CT2 | URLCT2 | URL | www.ez.no | + | Email CT2 | EmailCT2 | Email address | nospam@ez.no | + | Textline CT2 | TextlineCT2 | Text line | TestTextLine | + | ISBN CT2 | IsbnCT2 | ISBN | 9783161484100 | + | Authors CT2 | AuthorsCT2 | Authors | AuthorName,nospam@ez.no | + | Text block CT2 | TextBlockCT2 | Text block | TestTextBlock | + | Checkbox CT2 | CheckboxCT2 | Checkbox | true | + | Country CT2 | CountryCT2 | Country | FR | + | Date CT2 | DateCT2 | Date | 2018-12-31 | + | Time CT2 | TimeCT2 | Time | 13:55:00 | + | Float CT2 | FloatCT2 | Float | 2.34 | + | Integer CT2 | Integer2 | Integer | 10 | + | Map location CT2 | MapLocationCT2 | Map location | Tokio | + | Date and time CT2 | DateAndTimeCT2 | Date and time | 2018-12-31 13:55:00 | + | Content relation CT2 | ContentRelationCT2 | Content relation (single) | /RelationFolder1 | + | Content relations CT2 | ContentRelationsCT2 | Content relations (multiple) | RelationFolder1,/RelationFolder2 | + | Image CT2 | ImageCT2 | Image | /var/www/vendor/ezsystems/behatbundle/src/lib/Data/Images/small1.jpg | + | File CT2 | FileCT2 | File | /var/www/vendor/ezsystems/behatbundle/src/lib/Data/Files/file1.txt | + | Media CT2 | MediaCT2 | Media | /var/www/vendor/ezsystems/behatbundle/src/lib/Data/Videos/video1.mp4 | diff --git a/features/user_roles.feature b/features/examples/user_roles.feature similarity index 100% rename from features/user_roles.feature rename to features/examples/user_roles.feature diff --git a/src/bundle/Resources/config/services.yaml b/src/bundle/Resources/config/services.yaml index 8c53fb4b..1d8ba370 100644 --- a/src/bundle/Resources/config/services.yaml +++ b/src/bundle/Resources/config/services.yaml @@ -13,24 +13,22 @@ services: - '@ezpublish.api.service.content_type' - '@ezpublish.api.service.content' - ezbehatbundle.api.facade.contentfacade: - class: EzSystems\Behat\API\Facade\ContentFacade + EzSystems\Behat\API\Facade\ContentFacade: public: true - ezbehatbundle.api.facade.contenttypefacade: - class: EzSystems\Behat\API\Facade\ContentTypeFacade + EzSystems\Behat\API\Facade\ContentTypeFacade: public: true - ezbehatbundle.api.facade.rolefacade: - class: EzSystems\Behat\API\Facade\RoleFacade + EzSystems\Behat\API\Facade\RoleFacade: public: true - ezbehatbundle.api.facade.userfacade: - class: EzSystems\Behat\API\Facade\UserFacade + EzSystems\Behat\API\Facade\UserFacade: public: true - ezbehatbundle.api.facade.languagefacade: - class: EzSystems\Behat\API\Facade\LanguageFacade + EzSystems\Behat\API\Facade\LanguageFacade: + public: true + + EzSystems\Behat\Core\Behat\ArgumentParser: public: true ezbehatbundle.controller.exception: diff --git a/src/lib/API/ContentData/ContentDataProvider.php b/src/lib/API/ContentData/ContentDataProvider.php index 6142ab3e..6e00c4ca 100644 --- a/src/lib/API/ContentData/ContentDataProvider.php +++ b/src/lib/API/ContentData/ContentDataProvider.php @@ -9,6 +9,8 @@ use eZ\Publish\API\Repository\ContentService; use eZ\Publish\API\Repository\ContentTypeService; use eZ\Publish\API\Repository\Values\Content\ContentCreateStruct; +use eZ\Publish\API\Repository\Values\Content\ContentStruct; +use eZ\Publish\API\Repository\Values\ContentType\FieldDefinition; use EzSystems\Behat\API\ContentData\FieldTypeData\FieldTypeDataProviderInterface; class ContentDataProvider @@ -47,23 +49,35 @@ public function getRandomContentData($language): ContentCreateStruct $fieldDefinitions = $contentType->getFieldDefinitions(); foreach ($fieldDefinitions as $field) { - $fieldData = $this->getFieldData($field->fieldTypeIdentifier, $language); + $fieldData = $this->getRandomFieldData($field->fieldTypeIdentifier, $language); $contentCreateStruct->setField($field->identifier, $fieldData, $language); } return $contentCreateStruct; } - public function getFilledContentDataStruct(ContentCreateStruct $contentCreateStruct, $contentItemData, $language): ContentCreateStruct + public function getFilledContentDataStruct(ContentStruct $contentStruct, $contentItemData, $language): ContentStruct { + $contentType = $this->contentTypeService->loadContentTypeByIdentifier($this->contentTypeIdentifier); + $fieldDefinitions = $contentType->getFieldDefinitions(); + foreach ($contentItemData as $fieldIdentifier => $value) { - $contentCreateStruct->setField($fieldIdentifier, $value); + $fieldDefinition = array_values(array_filter($fieldDefinitions, function (FieldDefinition $fieldDefinition) use ($fieldIdentifier) { + return $fieldDefinition->identifier === $fieldIdentifier; + })); + + if (empty($fieldDefinition)) { + throw new \Exception(sprintf('Could not find fieldIdentifier: %s in content type: %s', $fieldIdentifier, $this->contentTypeIdentifier)); + } + + $fieldData = $this->getFieldDataFromString($fieldDefinition[0]->fieldTypeIdentifier, $value); + $contentStruct->setField($fieldIdentifier, $fieldData, $language); } - return $contentCreateStruct; + return $contentStruct; } - public function getFieldData($fieldIdentifier, $language = 'eng-GB') + public function getRandomFieldData($fieldIdentifier, $language = 'eng-GB') { foreach ($this->fieldTypeDataProviders as $provider) { if ($provider->supports($fieldIdentifier)) { @@ -71,4 +85,13 @@ public function getFieldData($fieldIdentifier, $language = 'eng-GB') } } } + + public function getFieldDataFromString($fieldIdentifier, $value) + { + foreach ($this->fieldTypeDataProviders as $provider) { + if ($provider->supports($fieldIdentifier)) { + return $provider->parseFromString($value); + } + } + } } diff --git a/src/lib/API/ContentData/FieldTypeData/AuthorDataProvider.php b/src/lib/API/ContentData/FieldTypeData/AuthorDataProvider.php index d94a6c36..2e033ad4 100644 --- a/src/lib/API/ContentData/FieldTypeData/AuthorDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/AuthorDataProvider.php @@ -16,19 +16,30 @@ public function supports(string $fieldTypeIdentifier): bool return $fieldTypeIdentifier === 'ezauthor'; } - public function generateData(string $language = 'eng-GB') + public function generateData(string $language = 'eng-GB'): Value { return new Value([$this->getSingleAuthor($language), $this->getSingleAuthor($language)]); } private function getSingleAuthor(string $language = 'eng-GB'): Author { - $author = new Author(); - $this->setLanguage($language); + + $author = new Author(); $author->name = $this->getFaker()->name; $author->email = $this->getFaker()->email; return $author; } + + public function parseFromString(string $value): Value + { + [$name, $email] = explode(',', $value); + + $author = new Author(); + $author->name = $name; + $author->email = $email; + + return new Value([$author]); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/BinaryFileDataProvider.php b/src/lib/API/ContentData/FieldTypeData/BinaryFileDataProvider.php index fce6cf29..86735c75 100644 --- a/src/lib/API/ContentData/FieldTypeData/BinaryFileDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/BinaryFileDataProvider.php @@ -28,4 +28,9 @@ public function generateData(string $language = 'eng-GB') return new Value(['inputUri' => $filePath]); } + + public function parseFromString(string $value) + { + return new Value(['inputUri' => $value]); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/BooleanDataProvider.php b/src/lib/API/ContentData/FieldTypeData/BooleanDataProvider.php index 62542e17..2d068256 100644 --- a/src/lib/API/ContentData/FieldTypeData/BooleanDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/BooleanDataProvider.php @@ -18,4 +18,9 @@ public function generateData(string $language = 'eng-GB') // if the field is required then the value has to be true. return true; } + + public function parseFromString(string $value) + { + return $value === 'true'; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/CountryDataProvider.php b/src/lib/API/ContentData/FieldTypeData/CountryDataProvider.php index 25ea49a7..8a741592 100644 --- a/src/lib/API/ContentData/FieldTypeData/CountryDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/CountryDataProvider.php @@ -36,4 +36,9 @@ public function generateData(string $language = 'eng-GB') return new Value([$randomCountry => self::COUNTRY_DATA[$randomCountry]]); } + + public function parseFromString(string $value) + { + return new Value([$value => self::COUNTRY_DATA[$value]]); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/DateDataProvider.php b/src/lib/API/ContentData/FieldTypeData/DateDataProvider.php index 72b673cb..370e9d7f 100644 --- a/src/lib/API/ContentData/FieldTypeData/DateDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/DateDataProvider.php @@ -6,6 +6,7 @@ */ namespace EzSystems\Behat\API\ContentData\FieldTypeData; +use DateTime; use eZ\Publish\Core\FieldType\Date\Value; class DateDataProvider extends RandomDataGenerator implements FieldTypeDataProviderInterface @@ -19,4 +20,9 @@ public function generateData(string $language = 'eng-GB') { return new Value($this->getFaker()->dateTimeThisCentury()); } + + public function parseFromString(string $value) + { + return DateTime::createFromFormat('Y-m-d', $value); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/DateTimeDataProvider.php b/src/lib/API/ContentData/FieldTypeData/DateTimeDataProvider.php index a14e23e6..1cccb62f 100644 --- a/src/lib/API/ContentData/FieldTypeData/DateTimeDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/DateTimeDataProvider.php @@ -6,6 +6,7 @@ */ namespace EzSystems\Behat\API\ContentData\FieldTypeData; +use DateTime; use eZ\Publish\Core\FieldType\DateAndTime\Value; class DateTimeDataProvider extends RandomDataGenerator implements FieldTypeDataProviderInterface @@ -19,4 +20,9 @@ public function generateData(string $language = 'eng-GB') { return new Value($this->getFaker()->dateTimeThisCentury()); } + + public function parseFromString(string $value) + { + return DateTime::createFromFormat('Y-m-d H:i:s', $value); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/EmailDataProvider.php b/src/lib/API/ContentData/FieldTypeData/EmailDataProvider.php index 08af67ea..59dd7642 100644 --- a/src/lib/API/ContentData/FieldTypeData/EmailDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/EmailDataProvider.php @@ -19,4 +19,9 @@ public function generateData(string $language = 'eng-GB'): string return $this->getFaker()->companyEmail; } + + public function parseFromString(string $value) + { + return $value; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/FieldTypeDataProviderInterface.php b/src/lib/API/ContentData/FieldTypeData/FieldTypeDataProviderInterface.php index fc547c15..ea2d5408 100644 --- a/src/lib/API/ContentData/FieldTypeData/FieldTypeDataProviderInterface.php +++ b/src/lib/API/ContentData/FieldTypeData/FieldTypeDataProviderInterface.php @@ -13,4 +13,6 @@ interface FieldTypeDataProviderInterface public function supports(string $fieldTypeIdentifier): bool; public function generateData(string $language = 'eng-GB'); + + public function parseFromString(string $value); } diff --git a/src/lib/API/ContentData/FieldTypeData/FloatDataProvider.php b/src/lib/API/ContentData/FieldTypeData/FloatDataProvider.php index c2356cbf..4e3e3167 100644 --- a/src/lib/API/ContentData/FieldTypeData/FloatDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/FloatDataProvider.php @@ -17,4 +17,9 @@ public function generateData(string $language = 'eng-GB') { return $this->getFaker()->randomFloat(4); } + + public function parseFromString(string $value) + { + return (float) $value; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/ISBNDataProvider.php b/src/lib/API/ContentData/FieldTypeData/ISBNDataProvider.php index a2e875b6..2913421e 100644 --- a/src/lib/API/ContentData/FieldTypeData/ISBNDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/ISBNDataProvider.php @@ -17,4 +17,9 @@ public function generateData(string $language = 'eng-GB') { return $this->getFaker()->isbn13; } + + public function parseFromString(string $value) + { + return $value; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/ImageDataProvider.php b/src/lib/API/ContentData/FieldTypeData/ImageDataProvider.php index 6368b6a7..3060ff8e 100644 --- a/src/lib/API/ContentData/FieldTypeData/ImageDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/ImageDataProvider.php @@ -44,4 +44,16 @@ public function generateData(string $language = 'eng-GB') ] ); } + + public function parseFromString(string $value) + { + return new Value( + [ + 'path' => $value, + 'fileSize' => filesize($value), + 'fileName' => basename($value), + 'alternativeText' => $value, + ] + ); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/IntegerDataProvider.php b/src/lib/API/ContentData/FieldTypeData/IntegerDataProvider.php index 41371fbc..86046f3c 100644 --- a/src/lib/API/ContentData/FieldTypeData/IntegerDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/IntegerDataProvider.php @@ -17,4 +17,9 @@ public function generateData(string $language = 'eng-GB') { return (int) $this->getFaker()->numerify('########'); } + + public function parseFromString(string $value) + { + return (int) $value; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/MapDataProvider.php b/src/lib/API/ContentData/FieldTypeData/MapDataProvider.php index 626dc23e..380d4b15 100644 --- a/src/lib/API/ContentData/FieldTypeData/MapDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/MapDataProvider.php @@ -42,4 +42,9 @@ public function generateData(string $language = 'eng-GB') { return new Value(self::LOCATION_DATA[array_rand(self::LOCATION_DATA, 1)]); } + + public function parseFromString(string $value) + { + return new Value(self::LOCATION_DATA[$value]); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/MediaDataProvider.php b/src/lib/API/ContentData/FieldTypeData/MediaDataProvider.php index 8675d8fe..9dcf4159 100644 --- a/src/lib/API/ContentData/FieldTypeData/MediaDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/MediaDataProvider.php @@ -34,4 +34,14 @@ public function generateData(string $language = 'eng-GB') return $value; } + + public function parseFromString(string $value) + { + $mediaValue = new Value(['inputUri' => $value]); + $mediaValue->hasController = true; + $mediaValue->autoplay = true; + $mediaValue->loop = true; + + return $mediaValue; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/ObjectRelationDataProvider.php b/src/lib/API/ContentData/FieldTypeData/ObjectRelationDataProvider.php index 9073f643..369b0e8f 100644 --- a/src/lib/API/ContentData/FieldTypeData/ObjectRelationDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/ObjectRelationDataProvider.php @@ -7,22 +7,38 @@ namespace EzSystems\Behat\API\ContentData\FieldTypeData; use eZ\Publish\API\Repository\ContentService; -use eZ\Publish\API\Repository\Exceptions\NotFoundException; -use eZ\Publish\API\Repository\Exceptions\UnauthorizedException; +use eZ\Publish\API\Repository\LocationService; use eZ\Publish\API\Repository\SearchService; +use eZ\Publish\API\Repository\URLAliasService; use eZ\Publish\API\Repository\Values\Content\Query; use eZ\Publish\API\Repository\Values\Content\Search\SearchHit; use eZ\Publish\Core\FieldType\Relation\Value; +use EzSystems\Behat\Core\Behat\ArgumentParser; class ObjectRelationDataProvider implements FieldTypeDataProviderInterface { + /** @var SearchService */ private $searchService; + + /** @var ContentService */ private $contentService; - public function __construct(SearchService $searchService, ContentService $contentService) + /** @var LocationService */ + private $locationService; + + /** @var URLAliasService */ + private $urlAliasService; + + /** @var ArgumentParser */ + private $argumentParser; + + public function __construct(SearchService $searchService, ContentService $contentService, LocationService $locationSerice, URLAliasService $urlAliasSerivce, ArgumentParser $argumentParser) { $this->searchService = $searchService; $this->contentService = $contentService; + $this->locationService = $locationSerice; + $this->urlAliasService = $urlAliasSerivce; + $this->argumentParser = $argumentParser; } public function supports(string $fieldTypeIdentifier): bool @@ -46,16 +62,6 @@ protected function getRandomContentIds(int $number) return $result->valueObject->contentInfo->id; }, $results->searchHits); - $contentIDs = array_filter($contentIDs, function (int $contentID) { - try { - $this->contentService->loadContentInfo($contentID); - - return true; - } catch (NotFoundException $e) { - } catch (UnauthorizedException $e) { - } - }); - $indices = array_rand($contentIDs, $number); if ($number === 1) { @@ -70,4 +76,19 @@ protected function getRandomContentIds(int $number) return $randomContentIDs; } + + public function parseFromString(string $value) + { + return new Value($this->getContentID($value)); + } + + protected function getContentID(string $locationPath) + { + $locationURL = $this->argumentParser->parseUrl($locationPath); + $urlAlias = $this->urlAliasService->lookup($locationURL); + + $location = $this->locationService->loadLocation($urlAlias->destination); + + return $location->getContentInfo()->id; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/ObjectRelationListDataProvider.php b/src/lib/API/ContentData/FieldTypeData/ObjectRelationListDataProvider.php index befba569..0fd9c27f 100644 --- a/src/lib/API/ContentData/FieldTypeData/ObjectRelationListDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/ObjectRelationListDataProvider.php @@ -19,4 +19,14 @@ public function generateData(string $language = 'eng-GB') { return new Value($this->getRandomContentIds(3)); } + + public function parseFromString(string $value) + { + $itemsToAdd = []; + foreach (explode(',', $value) as $itemToAdd) { + $itemsToAdd[] = $this->getContentID($itemToAdd); + } + + return new Value($itemsToAdd); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/PasswordProvider.php b/src/lib/API/ContentData/FieldTypeData/PasswordProvider.php index f675b2be..5d836b5f 100644 --- a/src/lib/API/ContentData/FieldTypeData/PasswordProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/PasswordProvider.php @@ -8,6 +8,8 @@ class PasswordProvider implements FieldTypeDataProviderInterface { + public const DEFAUlT_PASSWORD = 'Passw0rd-42'; + public function supports(string $fieldTypeIdentifier): bool { return $fieldTypeIdentifier === 'password'; @@ -15,6 +17,11 @@ public function supports(string $fieldTypeIdentifier): bool public function generateData(string $language = 'eng-GB'): string { - return 'Passw0rd-42'; + return self::DEFAUlT_PASSWORD; + } + + public function parseFromString(string $value) + { + return $value; } } diff --git a/src/lib/API/ContentData/FieldTypeData/RandomDataGenerator.php b/src/lib/API/ContentData/FieldTypeData/RandomDataGenerator.php index ec863687..15ce0772 100644 --- a/src/lib/API/ContentData/FieldTypeData/RandomDataGenerator.php +++ b/src/lib/API/ContentData/FieldTypeData/RandomDataGenerator.php @@ -37,6 +37,9 @@ public function setLanguage($language) protected function getFaker(): Generator { + // Workaround for Faker memory issues, see: https://github.com/fzaninotto/Faker/issues/1125#issuecomment-268676186 + gc_collect_cycles(); + return self::$faker; } } diff --git a/src/lib/API/ContentData/FieldTypeData/RichTextDataProvider.php b/src/lib/API/ContentData/FieldTypeData/RichTextDataProvider.php index a8dd88d4..ac814454 100644 --- a/src/lib/API/ContentData/FieldTypeData/RichTextDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/RichTextDataProvider.php @@ -24,4 +24,9 @@ public function generateData(string $language = 'eng-GB'): string return sprintf(self::RICHTEXT_XML, $this->getFaker()->realText()); } + + public function parseFromString(string $value) + { + return sprintf(self::RICHTEXT_XML, $value); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/StringDataProvider.php b/src/lib/API/ContentData/FieldTypeData/StringDataProvider.php index feb0c4ca..2fd6b70f 100644 --- a/src/lib/API/ContentData/FieldTypeData/StringDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/StringDataProvider.php @@ -19,4 +19,9 @@ public function generateData(string $language = 'eng-GB'): string return $this->getFaker()->realText(80, 1); } + + public function parseFromString(string $value) + { + return $value; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/TextLineDataProvider.php b/src/lib/API/ContentData/FieldTypeData/TextLineDataProvider.php index aae57a48..448dd299 100644 --- a/src/lib/API/ContentData/FieldTypeData/TextLineDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/TextLineDataProvider.php @@ -19,4 +19,9 @@ public function generateData(string $language = 'eng-GB'): string return $this->getFaker()->paragraphs(5, true); } + + public function parseFromString(string $value) + { + return $value; + } } diff --git a/src/lib/API/ContentData/FieldTypeData/TimeDataProvider.php b/src/lib/API/ContentData/FieldTypeData/TimeDataProvider.php index f46a4bc9..9b29e32f 100644 --- a/src/lib/API/ContentData/FieldTypeData/TimeDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/TimeDataProvider.php @@ -6,6 +6,7 @@ */ namespace EzSystems\Behat\API\ContentData\FieldTypeData; +use DateTime; use eZ\Publish\Core\FieldType\Time\Value; class TimeDataProvider extends RandomDataGenerator implements FieldTypeDataProviderInterface @@ -19,4 +20,9 @@ public function generateData(string $language = 'eng-GB') { return Value::fromDateTime($this->getFaker()->dateTimeThisCentury()); } + + public function parseFromString(string $value) + { + return Value::fromDateTime(DateTime::createFromFormat('H:i:s', $value)); + } } diff --git a/src/lib/API/ContentData/FieldTypeData/URLDataProvider.php b/src/lib/API/ContentData/FieldTypeData/URLDataProvider.php index a6b3dfb4..3ec30283 100644 --- a/src/lib/API/ContentData/FieldTypeData/URLDataProvider.php +++ b/src/lib/API/ContentData/FieldTypeData/URLDataProvider.php @@ -17,4 +17,9 @@ public function generateData(string $language = 'eng-GB') { return $this->getFaker()->url; } + + public function parseFromString(string $value) + { + return $value; + } } diff --git a/src/lib/API/Context/ContentContext.php b/src/lib/API/Context/ContentContext.php index 8f89873a..a3ee8f45 100644 --- a/src/lib/API/Context/ContentContext.php +++ b/src/lib/API/Context/ContentContext.php @@ -9,15 +9,20 @@ use Behat\Behat\Context\Context; use Behat\Gherkin\Node\TableNode; use EzSystems\Behat\API\Facade\ContentFacade; +use EzSystems\Behat\Core\Behat\ArgumentParser; class ContentContext implements Context { /** @var ContentFacade */ private $contentFacade; - public function __construct(ContentFacade $contentFacade) + /** @var ArgumentParser */ + private $argumentParser; + + public function __construct(ContentFacade $contentFacade, ArgumentParser $argumentParser) { $this->contentFacade = $contentFacade; + $this->argumentParser = $argumentParser; } /** @@ -25,13 +30,11 @@ public function __construct(ContentFacade $contentFacade) */ public function createMultipleContentItems(string $numberOfItems, string $contentTypeIdentifier, string $parentUrl, $language): void { - $parentUrl = $this->parseUrl($parentUrl); + $parentUrl = $this->argumentParser->parseUrl($parentUrl); for ($i = 0; $i < $numberOfItems; ++$i) { $this->contentFacade->createContent($contentTypeIdentifier, $parentUrl, $language); - gc_collect_cycles(); } - gc_collect_cycles(); } /** @@ -39,7 +42,7 @@ public function createMultipleContentItems(string $numberOfItems, string $conten */ public function createContentItems($contentTypeIdentifier, $parentUrl, $language, TableNode $contentItemsData): void { - $parentUrl = $this->parseUrl($parentUrl); + $parentUrl = $this->argumentParser->parseUrl($parentUrl); $parsedContentItemData = $this->parseData($contentItemsData); foreach ($parsedContentItemData as $contentItemData) { @@ -47,15 +50,17 @@ public function createContentItems($contentTypeIdentifier, $parentUrl, $language } } - private function parseUrl(string $url) + /** + * @Given I edit :locationURL Content item in :language + */ + public function editContentItem($locationURL, $language, TableNode $contentItemsData): void { - if ($url === 'root') { - return '/'; - } - - $url = str_replace(' ', '-', $url); + $locationURL = $this->argumentParser->parseUrl($locationURL); + $parsedContentItemData = $this->parseData($contentItemsData); - return strpos($url, '/') === 0 ? $url : sprintf('/%s', $url); + foreach ($parsedContentItemData as $contentItemData) { + $this->contentFacade->editContent($locationURL, $language, $contentItemData); + } } private function parseData(TableNode $contentItemData) diff --git a/src/lib/API/Facade/ContentFacade.php b/src/lib/API/Facade/ContentFacade.php index b320fc5a..87ac61d8 100644 --- a/src/lib/API/Facade/ContentFacade.php +++ b/src/lib/API/Facade/ContentFacade.php @@ -54,4 +54,20 @@ public function createContent($contentTypeIdentifier, $parentUrl, $language, $co $draft = $this->contentService->createContent($contentCreateStruct, [$locationCreateStruct]); $this->contentService->publishVersion($draft->versionInfo); } + + public function editContent($locationURL, $language, $contentItemData) + { + $urlAlias = $this->urlAliasService->lookup($locationURL); + Assert::assertEquals(URLAlias::LOCATION, $urlAlias->type); + + $location = $this->locationService->loadLocation($urlAlias->destination); + $contentDraft = $this->contentService->createContentDraft($location->getContentInfo()); + $contentUpdateStruct = $this->contentService->newContentUpdateStruct(); + + $this->contentDataProvider->setContentTypeIdentifier($contentDraft->getContentType()->identifier); + $this->contentDataProvider->getFilledContentDataStruct($contentUpdateStruct, $contentItemData, $language); + + $updatedDraft = $this->contentService->updateContent($contentDraft->getVersionInfo(), $contentUpdateStruct); + $this->contentService->publishVersion($updatedDraft->getVersionInfo()); + } } diff --git a/src/lib/API/Facade/UserFacade.php b/src/lib/API/Facade/UserFacade.php index 0e75a99b..25aee0bc 100644 --- a/src/lib/API/Facade/UserFacade.php +++ b/src/lib/API/Facade/UserFacade.php @@ -14,6 +14,7 @@ use eZ\Publish\API\Repository\Values\Content\Query\Criterion; use eZ\Publish\API\Repository\Values\User\UserGroup; use EzSystems\Behat\API\ContentData\ContentDataProvider; +use EzSystems\Behat\API\ContentData\FieldTypeData\PasswordProvider; class UserFacade { @@ -52,13 +53,13 @@ public function createUser($userName, $userGroupName = null, $languageCode = 'en { $userCreateStruct = $this->userService->newUserCreateStruct( $userName, - $this->contentDataProvider->getFieldData('email', $languageCode), - $this->contentDataProvider->getFieldData('password', $languageCode), + $this->contentDataProvider->getRandomFieldData('email', $languageCode), + $this->getDefaultPassword(), $languageCode, $this->contentTypeService->loadContentTypeByIdentifier(self::USER_CONTENT_TYPE_IDENTIFIER)); $userCreateStruct->setField('first_name', $userName); - $userCreateStruct->setField('last_name', $this->contentDataProvider->getFieldData('ezstring', $languageCode)); + $userCreateStruct->setField('last_name', $this->contentDataProvider->getRandomFieldData('ezstring', $languageCode)); $parentGroup = $userGroupName !== null ? $this->loadUserGroupByName($userGroupName) : @@ -85,7 +86,7 @@ public function assignUserGroupToRole($userGroupName, $roleName) public function getDefaultPassword(): string { - return $this->contentDataProvider->getFieldData('password'); + return PasswordProvider::DEFAUlT_PASSWORD; } private function loadUserGroupByName(string $userGroupName): UserGroup diff --git a/src/lib/Core/Behat/ArgumentParser.php b/src/lib/Core/Behat/ArgumentParser.php new file mode 100644 index 00000000..40fcf31c --- /dev/null +++ b/src/lib/Core/Behat/ArgumentParser.php @@ -0,0 +1,21 @@ +