Completed
Push — master ( 45d3b1...40b0e0 )
by Rafael
04:30
created

shouldNotExistInRepositoryARecordMatching()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 2
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 Ynlo\GraphQLBundle\Behat\Client\ClientAwareInterface;
20
use Ynlo\GraphQLBundle\Behat\Client\ClientAwareTrait;
21
use Ynlo\GraphQLBundle\Behat\Gherkin\YamlStringNode;
22
use Ynlo\GraphQLBundle\Behat\Storage\StorageAwareInterface;
23
use Ynlo\GraphQLBundle\Behat\Storage\StorageAwareTrait;
24
25
/**
26
 * Context for Doctrine integration
27
 *
28
 * @property KernelInterface $kernel
29
 */
30
final class DoctrineContext implements Context, ClientAwareInterface, StorageAwareInterface
31
{
32
    use ClientAwareTrait;
33
    use StorageAwareTrait;
34
35
    /**
36
     * Use a YAML syntax to create a criteria to match a record in given repository
37
     *
38
     * Example: Then should exist in repository "AppBundle:Post" a record matching:
39
     *   """
40
     *   title: "Welcome"
41
     *   body: "Welcome to web page"
42
     *   """
43
     *
44
     * Expression syntax is allowed
45
     *
46
     * Example: Then should exist in table "post" a record matching:
47
     *   """
48
     *   title: "{variables.input.title}"
49
     *   body: "{variables.input.body}"
50
     *   """
51
     *
52
     * @Given /^should exist in repository "([^"]*)" a record matching:$/
53
     */
54
    public function shouldExistInRepositoryARecordMatching($repo, YamlStringNode $criteria)
55
    {
56
        $exists = (boolean) $this->getDoctrine()->getRepository($repo)->findOneBy($criteria->toArray());
57
        Assert::assertTrue($exists, sprintf('Does not exist any record in the repository "%s" matching given conditions', $repo));
58
    }
59
60
    /**
61
     * Use a YAML syntax to create a criteria to match a record in given repository
62
     *
63
     * Example: Then should not exist in repository "AppBundle:Post" a record matching:
64
     *   """
65
     *   title: "Welcome"
66
     *   body: "Welcome to web page"
67
     *   """
68
     *
69
     * Expression syntax is allowed
70
     *
71
     * Example: Then should not exist in table "post" a record matching:
72
     *   """
73
     *   title: "{variables.input.title}"
74
     *   body: "{variables.input.body}"
75
     *   """
76
     *
77
     * @Given /^should not exist in repository "([^"]*)" a record matching:$/
78
     */
79
    public function shouldNotExistInRepositoryARecordMatching($repo, YamlStringNode $criteria)
80
    {
81
        $exists = (boolean) $this->getDoctrine()->getRepository($repo)->findOneBy($criteria->toArray());
82
        Assert::assertFalse($exists, sprintf('Exist at least one record in the repository "%s" matching given conditions', $repo));
83
    }
84
85
    /**
86
     * Grab a set of records from database in a temp variable inside the `"storage"` in order to use latter in an expression
87
     *
88
     * The prefix `"grab in"` is optional and can be used in "Then" for readability
89
     *
90
     * <code>
91
     * Given "users" from ....
92
     * Then grab in "users" from ...
93
     * </code>
94
     *
95
     * The suffix `"matching:"` is optional too and can be used to set array of conditions to match.
96
     *
97
     * ### Placeholders:
98
     * - **$variable:** `(string)` name of the variable to save in the storage
99
     * - **$entity:** `(string)` name of the entity using bundle notation `"AppBundle:Entity"` or FQN
100
     * - **$limitAndOffset:** `(int|string)` amount of records to fetch `"limit"` or use `"limit:offset"` to use pagination
101
     * - **$orderBy:** `(string|array)` string like `"title:ASC"` or array inside expression like `"{ [{status: 'DESC', title: 'ASC'}] }"`
102
     * - **$criteria:** `(yaml)` YAML node to convert to array of criteria
103
     *
104
     * ### Examples:
105
     *
106
     * <code>
107
     * - Given "orderedUsers" from repository "AppBundle:User" first 5 records ordered by "username:ASC" matching:
108
     *          """
109
     *          enabled: true
110
     *          """
111
     * - Given "orderedUsers" from repository "AppBundle:User" first 5 records ordered by "username:ASC"
112
     * - And "orderedUsersWithOffset" from repository "AppBundle:User" first "10:20" records ordered by "username:ASC"
113
     * - Then grab in "orderedPosts" from repository "AppBundle:Post" first 10 records ordered by "{ [{status: 'DESC', title: 'ASC'}] }"
114
     * </code>
115
     *
116
     * and later can be used:
117
     *
118
     * <code>
119
     * - And "{orderedUsers[0].getUsername()}" should be equal to "{response.data.users.all.edges[0].node.login}"
120
     * </code>
121
     *
122
     * @Given /^(?:grab in )?"([^"]*)" from repository "([^"]*)" first "?([^"]*)"? records ordered by "([^"]*)"(?: matching:)?$/
123
     */
124
    public function grabInFromRepositoryFirstRecordsOrderedByMatching($variable, $repo, $limitAndOffset = null, $orderBy = null, YamlStringNode $criteria = null)
125
    {
126
        //support to use "limit:offset"
127
        if (strpos($limitAndOffset, ':') !== false) {
128
            list($limit, $offset) = explode(':', $limitAndOffset);
129
        } else {
130
            $limit = $limitAndOffset;
131
            $offset = null;
132
        }
133
        // support field:ORDER, eg. name:ASC
134
        if (is_string($orderBy)) {
135
            list($field, $order) = explode(':', $orderBy);
136
            $orderBy = [$field => $order];
137
        }
138
        $records = $this->getDoctrine()
139
                        ->getRepository($repo)
140
                        ->findBy($criteria ? $criteria->toArray() : [], $orderBy, $limit, $offset);
0 ignored issues
show
Bug introduced by
It seems like $offset can also be of type string; however, parameter $offset of Doctrine\Common\Persiste...ectRepository::findBy() does only seem to accept null|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

140
                        ->findBy($criteria ? $criteria->toArray() : [], $orderBy, $limit, /** @scrutinizer ignore-type */ $offset);
Loading history...
141
        $this->storage->setValue($variable, $records);
142
    }
143
144
    public function getDoctrine(): Registry
145
    {
146
        return $this->client->getContainer()->get('doctrine');
147
    }
148
149
    /**
150
     * @param string $class
151
     *
152
     * @return ObjectRepository|EntityRepository
153
     */
154
    public function getRepository(string $class): ObjectRepository
155
    {
156
        return $this->getDoctrine()->getRepository($class);
157
    }
158
}
159