AssertsOutput::checkTransformerData()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
nc 3
nop 3
dl 0
loc 8
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Digitonic\ApiTestSuite\Concerns;
4
5
use Digitonic\ApiTestSuite\TestResponse;
6
use phpDocumentor\Reflection\Types\Boolean;
7
8
trait AssertsOutput
9
{
10
    protected $isCollection;
11
12
    protected $updateData;
13
14
    /**
15
     * @param array $data
16
     * @param $identifier
17
     * @param $included
18
     */
19
    protected function checkTransformerData(array $data, $identifier, $updatedAt = null)
20
    {
21
        if ($this->isCollection($data)) {
22
            foreach ($data as $entity) {
23
                $this->assertIndividualEntityTransformerData($entity, $identifier);
24
            }
25
        } else {
26
            $this->assertIndividualEntityTransformerData($data, $identifier, $updatedAt);
27
        }
28
    }
29
30
    /**
31
     * @param $data
32
     * @param $identifier
33
     * @param $included
34
     */
35
    protected function assertIndividualEntityTransformerData($data, $identifier, $updatedAt = null)
36
    {
37
        $this->assertTransformerReplacesKeys($data);
38
        $this->assertDataIsPresent($data);
39
        $this->assertTimestamps($data, $updatedAt);
40
        $this->assertLinks($data, $identifier);
41
    }
42
43
    /**
44
     * @param array $replacements
45
     * @param $data
46
     */
47
    protected function assertTransformerReplacesKeys(array $data)
48
    {
49
        if (!empty($this->fieldsReplacement())) {
0 ignored issues
show
Bug introduced by
It seems like fieldsReplacement() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

49
        if (!empty($this->/** @scrutinizer ignore-call */ fieldsReplacement())) {
Loading history...
50
            foreach ($this->fieldsReplacement() as $original => $replacement) {
51
                $this->assertArrayNotHasKey(
0 ignored issues
show
Bug introduced by
It seems like assertArrayNotHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
                $this->/** @scrutinizer ignore-call */ 
52
                       assertArrayNotHasKey(
Loading history...
52
                    $original,
53
                    $data,
54
                    'Field '
55
                    . $original
56
                    . ' should not be present in public facing data. Please make sure that '
57
                    . $replacement . ' is used instead or change the `shouldReplaceFields` method implementation'
58
                );
59
                $this->assertArrayHasKey(
0 ignored issues
show
Bug introduced by
It seems like assertArrayHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

59
                $this->/** @scrutinizer ignore-call */ 
60
                       assertArrayHasKey(
Loading history...
60
                    $replacement,
61
                    $data,
62
                    'Field ' . $replacement . ' should be present in public facing data instead of '
63
                    . $original . ' or change the `shouldReplaceFields` method implementation'
64
                );
65
            }
66
        }
67
    }
68
69
    /**
70
     * @param array $data
71
     */
72
    protected function assertDataIsPresent(array $data)
73
    {
74
        $expected = $this->expectedResourceData($data);
0 ignored issues
show
Bug introduced by
It seems like expectedResourceData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

74
        /** @scrutinizer ignore-call */ 
75
        $expected = $this->expectedResourceData($data);
Loading history...
75
        foreach ($expected as $key => $value) {
76
            $this->assertArrayHasKey($key, $data);
77
            if (!$this->isCollection) {
78
                $this->assertTrue(
0 ignored issues
show
Bug introduced by
It seems like assertTrue() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

78
                $this->/** @scrutinizer ignore-call */ 
79
                       assertTrue(
Loading history...
79
                    $expected[$key] == $data[$key],
80
                    'The output data \'' . print_r($data[$key], true)
81
                    . '\'for the key \'' . $key . '\' doesn\'t match the expected \''
82
                    . print_r($expected[$key], true) . '\''
83
                );
84
            }
85
        }
86
    }
87
88
    /**
89
     * @param $data
90
     */
91
    protected function assertTimestamps(array $data, ?string $updatedAt)
92
    {
93
        if ($this->expectsTimestamps()) {
0 ignored issues
show
Bug introduced by
It seems like expectsTimestamps() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

93
        if ($this->/** @scrutinizer ignore-call */ expectsTimestamps()) {
Loading history...
94
            $this->assertArrayHasKey('created_at', $data);
95
            $this->assertArrayHasKey('updated_at', $data);
96
            $this->assertIsString($data['created_at']);
0 ignored issues
show
Bug introduced by
It seems like assertIsString() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

96
            $this->/** @scrutinizer ignore-call */ 
97
                   assertIsString($data['created_at']);
Loading history...
97
            $this->assertIsString($data['updated_at']);
98
            if (!empty($updatedAt)) {
99
                $this->assertNotEquals(
0 ignored issues
show
Bug introduced by
It seems like assertNotEquals() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

99
                $this->/** @scrutinizer ignore-call */ 
100
                       assertNotEquals(
Loading history...
100
                    $updatedAt,
101
                    $data['updated_at'],
102
                    'The \'updated_at\' timestamp should change on update of the resource.'
103
                    . ' Make sure it is done by calling touch() on that entity if it\'s not updated directly.'
104
                );
105
            }
106
        }
107
    }
108
109
    /**
110
     * @param array $data
111
     * @param $identifier
112
     */
113
    protected function assertLinks(array $data, $identifier)
114
    {
115
        foreach ($this->expectedLinks() as $rel => $routeName) {
0 ignored issues
show
Bug introduced by
It seems like expectedLinks() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

115
        foreach ($this->/** @scrutinizer ignore-call */ expectedLinks() as $rel => $routeName) {
Loading history...
116
            $this->assertContains(
0 ignored issues
show
Bug introduced by
It seems like assertContains() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

116
            $this->/** @scrutinizer ignore-call */ 
117
                   assertContains(
Loading history...
117
                [
118
                    'rel' => $rel,
119
                    'uri' => route($routeName, $data[$identifier])
120
                ],
121
                $data['links']
122
            );
123
        }
124
    }
125
126
    protected function isCollection(array $data)
127
    {
128
        if (isset($this->isCollection)) {
129
            return $this->isCollection;
130
        }
131
132
        if (empty($data)) {
133
            $this->isCollection = false;
134
            return $this->isCollection;
135
        }
136
137
        $this->isCollection = array_reduce(
138
            $data,
139
            function ($carry, $item) {
140
                return $carry && is_array($item);
141
            },
142
            true
143
        );
144
145
        return $this->isCollection;
146
    }
147
148
    public function checkRequiredResponseHeaders(TestResponse $response): bool
149
    {
150
        return collect(
151
            array_keys($this->requiredResponseHeaders())
152
        )->reduce(
153
            function ($carry, $index) use ($response){
154
                return $carry && $response->assertHeader($index, $this->requiredResponseHeaders()[$index]);
155
            },
156
            true
157
        );
158
    }
159
160
    protected function requiredResponseHeaders()
161
    {
162
        return config('digitonic.api-test-suite.required_response_headers');
163
    }
164
}
165