ynloultratech /
graphql-bundle
| 1 | <?php |
||
| 2 | /******************************************************************************* |
||
| 3 | * This file is part of the GraphQL Bundle package. |
||
| 4 | * |
||
| 5 | * (c) YnloUltratech <[email protected]> |
||
| 6 | * |
||
| 7 | * For the full copyright and license information, please view the LICENSE |
||
| 8 | * file that was distributed with this source code. |
||
| 9 | ******************************************************************************/ |
||
| 10 | |||
| 11 | namespace Ynlo\GraphQLBundle\Behat\Context; |
||
| 12 | |||
| 13 | use Behat\Behat\Context\Context; |
||
| 14 | use Doctrine\Bundle\DoctrineBundle\Registry; |
||
| 15 | use Doctrine\Common\Persistence\ObjectRepository; |
||
| 16 | use Doctrine\ORM\EntityRepository; |
||
| 17 | use PHPUnit\Framework\Assert; |
||
| 18 | use Symfony\Component\HttpKernel\KernelInterface; |
||
| 19 | use Symfony\Component\PropertyAccess\PropertyAccessor; |
||
| 20 | use Ynlo\GraphQLBundle\Behat\Client\ClientAwareInterface; |
||
| 21 | use Ynlo\GraphQLBundle\Behat\Client\ClientAwareTrait; |
||
| 22 | use Ynlo\GraphQLBundle\Behat\Gherkin\YamlStringNode; |
||
| 23 | use Ynlo\GraphQLBundle\Behat\Storage\StorageAwareInterface; |
||
| 24 | use Ynlo\GraphQLBundle\Behat\Storage\StorageAwareTrait; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Context for Doctrine integration |
||
| 28 | * |
||
| 29 | * @property KernelInterface $kernel |
||
| 30 | */ |
||
| 31 | final class DoctrineContext implements Context, ClientAwareInterface, StorageAwareInterface |
||
| 32 | { |
||
| 33 | use ClientAwareTrait; |
||
| 34 | use StorageAwareTrait; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Use a YAML syntax to populate a repository with multiple records |
||
| 38 | * |
||
| 39 | * Example: Given the following records in the repository "App\Entity\Post" |
||
| 40 | * """ |
||
| 41 | * - title: "Welcome" |
||
| 42 | * body: "Welcome to web page" |
||
| 43 | * - title: "Another Post" |
||
| 44 | * body: "This is another post" |
||
| 45 | * """ |
||
| 46 | * |
||
| 47 | * @Given /^the following records in the repository "([^"]*)"$/ |
||
| 48 | */ |
||
| 49 | public function theFollowingRecordsInTheRepository($entity, YamlStringNode $records) |
||
| 50 | { |
||
| 51 | $manager = $this->getDoctrine()->getManager(); |
||
| 52 | $accessor = new PropertyAccessor(); |
||
| 53 | foreach ($records->toArray() as $record) { |
||
| 54 | $instance = new $entity(); |
||
| 55 | foreach ($record as $prop => $value) { |
||
| 56 | $accessor->setValue($instance, $prop, $value); |
||
| 57 | } |
||
| 58 | |||
| 59 | $manager->persist($instance); |
||
| 60 | } |
||
| 61 | $manager->flush(); |
||
| 62 | } |
||
| 63 | |||
| 64 | /** |
||
| 65 | * Use a YAML syntax to create a criteria to match a record in given repository |
||
| 66 | * |
||
| 67 | * Example: Then should exist in repository "AppBundle:Post" a record matching: |
||
| 68 | * """ |
||
| 69 | * title: "Welcome" |
||
| 70 | * body: "Welcome to web page" |
||
| 71 | * """ |
||
| 72 | * |
||
| 73 | * Expression syntax is allowed |
||
| 74 | * |
||
| 75 | * Example: Then should exist in table "post" a record matching: |
||
| 76 | * """ |
||
| 77 | * title: "{variables.input.title}" |
||
| 78 | * body: "{variables.input.body}" |
||
| 79 | * """ |
||
| 80 | * |
||
| 81 | * @Given /^should exist in repository "([^"]*)" a record matching:$/ |
||
| 82 | */ |
||
| 83 | public function shouldExistInRepositoryARecordMatching($repo, YamlStringNode $criteria) |
||
| 84 | { |
||
| 85 | $exists = (boolean) $this->getDoctrine()->getRepository($repo)->findOneBy($criteria->toArray()); |
||
| 86 | Assert::assertTrue($exists, sprintf('Does not exist any record in the repository "%s" matching given conditions', $repo)); |
||
| 87 | } |
||
| 88 | |||
| 89 | /** |
||
| 90 | * Use a YAML syntax to create a criteria to match a record in given repository |
||
| 91 | * |
||
| 92 | * Example: Then should not exist in repository "AppBundle:Post" a record matching: |
||
| 93 | * """ |
||
| 94 | * title: "Welcome" |
||
| 95 | * body: "Welcome to web page" |
||
| 96 | * """ |
||
| 97 | * |
||
| 98 | * Expression syntax is allowed |
||
| 99 | * |
||
| 100 | * Example: Then should not exist in table "post" a record matching: |
||
| 101 | * """ |
||
| 102 | * title: "{variables.input.title}" |
||
| 103 | * body: "{variables.input.body}" |
||
| 104 | * """ |
||
| 105 | * |
||
| 106 | * @Given /^should not exist in repository "([^"]*)" a record matching:$/ |
||
| 107 | */ |
||
| 108 | public function shouldNotExistInRepositoryARecordMatching($repo, YamlStringNode $criteria) |
||
| 109 | { |
||
| 110 | $exists = (boolean) $this->getDoctrine()->getRepository($repo)->findOneBy($criteria->toArray()); |
||
| 111 | Assert::assertFalse($exists, sprintf('Exist at least one record in the repository "%s" matching given conditions', $repo)); |
||
| 112 | } |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Grab a set of records from database in a temp variable inside the `"storage"` in order to use latter in an expression |
||
| 116 | * |
||
| 117 | * The prefix `"grab in"` is optional and can be used in "Then" for readability |
||
| 118 | * |
||
| 119 | * <code> |
||
| 120 | * Given "users" from .... |
||
| 121 | * Then grab in "users" from ... |
||
| 122 | * </code> |
||
| 123 | * |
||
| 124 | * The suffix `"matching:"` is optional too and can be used to set array of conditions to match. |
||
| 125 | * |
||
| 126 | * ### Placeholders: |
||
| 127 | * - **$variable:** `(string)` name of the variable to save in the storage |
||
| 128 | * - **$entity:** `(string)` name of the entity using bundle notation `"AppBundle:Entity"` or FQN |
||
| 129 | * - **$limitAndOffset:** `(int|string)` amount of records to fetch `"limit"` or use `"limit:offset"` to use pagination |
||
| 130 | * - **$orderBy:** `(string|array)` string like `"title:ASC"` or array inside expression like `"{ [{status: 'DESC', title: 'ASC'}] }"` |
||
| 131 | * - **$criteria:** `(yaml)` YAML node to convert to array of criteria |
||
| 132 | * |
||
| 133 | * ### Examples: |
||
| 134 | * |
||
| 135 | * <code> |
||
| 136 | * - Given "orderedUsers" from repository "AppBundle:User" first 5 records ordered by "username:ASC" matching: |
||
| 137 | * """ |
||
| 138 | * enabled: true |
||
| 139 | * """ |
||
| 140 | * - Given "orderedUsers" from repository "AppBundle:User" first 5 records ordered by "username:ASC" |
||
| 141 | * - And "orderedUsersWithOffset" from repository "AppBundle:User" first "10:20" records ordered by "username:ASC" |
||
| 142 | * - Then grab in "orderedPosts" from repository "AppBundle:Post" first 10 records ordered by "{ [{status: 'DESC', title: 'ASC'}] }" |
||
| 143 | * </code> |
||
| 144 | * |
||
| 145 | * and later can be used: |
||
| 146 | * |
||
| 147 | * <code> |
||
| 148 | * - And "{orderedUsers[0].getUsername()}" should be equal to "{response.data.users.all.edges[0].node.login}" |
||
| 149 | * </code> |
||
| 150 | * |
||
| 151 | * @Given /^(?:grab in )?"([^"]*)" from repository "([^"]*)" first "?([^"]*)"? records ordered by "([^"]*)"(?: matching:)?$/ |
||
| 152 | */ |
||
| 153 | public function grabInFromRepositoryFirstRecordsOrderedByMatching($variable, $repo, $limitAndOffset = null, $orderBy = null, YamlStringNode $criteria = null) |
||
| 154 | { |
||
| 155 | //support to use "limit:offset" |
||
| 156 | if (strpos($limitAndOffset, ':') !== false) { |
||
| 157 | list($limit, $offset) = explode(':', $limitAndOffset); |
||
| 158 | } else { |
||
| 159 | $limit = $limitAndOffset; |
||
| 160 | $offset = null; |
||
| 161 | } |
||
| 162 | // support field:ORDER, eg. name:ASC |
||
| 163 | if (is_string($orderBy)) { |
||
| 164 | list($field, $order) = explode(':', $orderBy); |
||
| 165 | $orderBy = [$field => $order]; |
||
| 166 | } |
||
| 167 | $records = $this->getDoctrine() |
||
| 168 | ->getRepository($repo) |
||
| 169 | ->findBy($criteria ? $criteria->toArray() : [], $orderBy, $limit, $offset); |
||
| 170 | $this->storage->setValue($variable, $records); |
||
| 171 | } |
||
| 172 | |||
| 173 | public function getDoctrine(): Registry |
||
| 174 | { |
||
| 175 | return $this->client->getContainer()->get('doctrine'); |
||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||
| 176 | } |
||
| 177 | |||
| 178 | /** |
||
| 179 | * @param string $class |
||
| 180 | * |
||
| 181 | * @return ObjectRepository|EntityRepository |
||
| 182 | */ |
||
| 183 | public function getRepository(string $class): ObjectRepository |
||
| 184 | { |
||
| 185 | return $this->getDoctrine()->getRepository($class); |
||
|
0 ignored issues
–
show
|
|||
| 186 | } |
||
| 187 | } |
||
| 188 |