Passed
Push — master ( 8b13f7...51f43c )
by Baptiste
02:23
created

src/PhpMatcher/JsonContext.php (1 issue)

Labels
Severity
1
<?php declare(strict_types=1);
2
namespace Behapi\PhpMatcher;
3
4
use InvalidArgumentException;
5
6
use Behat\Behat\Context\Context;
7
use Behat\Gherkin\Node\PyStringNode;
8
9
use Symfony\Component\PropertyAccess\PropertyAccess;
10
use Symfony\Component\PropertyAccess\PropertyAccessor;
11
12
use Behapi\Http\Response;
13
use Behapi\HttpHistory\History as HttpHistory;
14
15
use function sprintf;
16
use function json_encode;
17
use function json_decode;
18
19
class JsonContext implements Context
20
{
21
    use Response;
22
23
    /** @var MatcherFactory */
24
    private $factory;
25
26
    /** @var PropertyAccessor */
27
    private $accessor;
28
29
    public function __construct(HttpHistory $history)
30
    {
31
        $this->history = $history;
32
        $this->factory = new MatcherFactory;
33
        $this->accessor = PropertyAccess::createPropertyAccessor();
34
    }
35
36
    /** @Then the root should match: */
37
    final public function root_should_match(PyStringNode $pattern): void
38
    {
39
        $matcher = $this->factory->createMatcher();
40
41
        if ($matcher->match($this->getJson(), $pattern->getRaw())) {
42
            return;
43
        }
44
45
        throw new InvalidArgumentException(
46
            sprintf(
47
                'The json root does not match with the given pattern (error : %s)',
48
                $matcher->getError()
49
            )
50
        );
51
    }
52
53
    /** @Then in the json, :path should match: */
54
    final public function path_should_match(string $path, PyStringNode $pattern): void
55
    {
56
        $value = $this->getValue($path);
57
        $matcher = $this->factory->createMatcher();
58
59
        $json = json_encode($value);
60
61
        if ($matcher->match($json, $pattern->getRaw())) {
62
            return;
63
        }
64
65
        throw new InvalidArgumentException(
66
            sprintf(
67
                'The json path "%s" does not match with the given pattern (error : %s)',
68
                $path,
69
                $matcher->getError()
70
            )
71
        );
72
    }
73
74
    /** @Then in the json, :path should not match: */
75
    final public function path_should_not_match(string $path, PyStringNode $pattern): void
76
    {
77
        $value = $this->getValue($path);
78
        $matcher = $this->factory->createMatcher();
79
80
        $json = json_encode($value);
81
82
        if (!$matcher->match($json, $pattern->getRaw())) {
83
            return;
84
        }
85
86
        throw new InvalidArgumentException(
87
            sprintf(
88
                'The json path "%s" matches with the given pattern (error : %s)',
89
                $path,
90
                $matcher->getError()
91
            )
92
        );
93
    }
94
95
    private function getJson(): ?stdClass
0 ignored issues
show
The type Behapi\PhpMatcher\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
96
    {
97
        return json_decode((string) $this->getResponse()->getBody());
98
    }
99
100
    private function getValue(string $path)
101
    {
102
        $json = $this->getJson();
103
104
        if (null === $json) {
105
            throw new InvalidArgumentException('Expected a Json valid content, got none');
106
        }
107
108
        return $this->accessor->getValue($json, $path);
109
    }
110
}
111