-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFeatureContext.php
More file actions
164 lines (143 loc) · 5.02 KB
/
FeatureContext.php
File metadata and controls
164 lines (143 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?php
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\Step\Given;
use donatj\MockWebServer\MockWebServer;
use donatj\MockWebServer\RequestInfo;
use donatj\MockWebServer\Response as MockWebServerResponse;
use GuzzleHttp\Psr7\Response;
use Libresign\NextcloudBehat\NextcloudApiContext;
use PHPUnit\Framework\Assert;
require __DIR__ . '/../../vendor/autoload.php';
final class FeatureContext extends NextcloudApiContext {
protected MockWebServer $mockServer;
public function __construct(?array $parameters = []) {
parent::__construct($parameters);
$this->mockServer = new MockWebServer();
$this->mockServer->start();
$this->baseUrl = $this->mockServer->getServerRoot() . '/';
}
/**
* @inheritDoc
*/
#[\Override]
public function setCurrentUser(string $user): void {
parent::setCurrentUser($user);
Assert::assertEquals($this->currentUser, $user);
}
/**
* @inheritDoc
*/
#[\Override]
public function assureUserExists(string $user): void {
parent::assureUserExists($user);
$lastRequest = $this->getLastREquest();
$headers = $lastRequest->getHeaders();
Assert::assertEquals('/ocs/v2.php/cloud/users/test', $lastRequest->getRequestUri());
Assert::assertArrayHasKey('OCS-ApiRequest', $headers);
Assert::assertEquals('true', $headers['OCS-ApiRequest']);
Assert::assertArrayHasKey('Authorization', $headers);
Assert::assertArrayHasKey('Accept', $headers);
Assert::assertEquals('application/json', $headers['Accept']);
}
private function getLastRequest(): RequestInfo {
$lastRequest = $this->mockServer->getLastRequest();
if (!$lastRequest instanceof RequestInfo) {
throw new Exception('Invalid response');
}
return $lastRequest;
}
/**
* When whe run the test suit of this repository at GitHub Actions, is
* necessary to consider that we haven't Nextcloud installed and mock
* the real path of files.
*/
#[\Override]
public static function findParentDirContainingFile(string $filename): string {
return __DIR__;
}
/**
* @inheritDoc
*/
#[\Override]
public function sendRequest(string $verb, string $url, $body = null, array $headers = [], array $options = []): void {
parent::sendRequest($verb, $url, $body, $headers, $options);
$lastRequest = $this->getLastRequest();
$parsedInput = $this->getParsedInputFromRequest($lastRequest);
// Verb
Assert::assertEquals($verb, $lastRequest->getRequestMethod());
// Url
$actual = preg_replace('/^\/index.php/', '', $lastRequest->getRequestUri());
$url = $this->parseText($url);
Assert::assertEquals($url, $actual);
// Headers
Assert::assertCount(
count($this->requestOptions['headers']),
array_intersect_assoc($lastRequest->getHeaders(), $this->requestOptions['headers'])
);
// Form params
if (array_key_exists('form_params', $this->requestOptions)) {
Assert::assertEquals($this->requestOptions['form_params'], $parsedInput);
}
// JSON payload
if (array_key_exists('json', $this->requestOptions)) {
Assert::assertEquals($this->requestOptions['json'], $parsedInput);
}
// Raw body payload
if (array_key_exists('body', $this->requestOptions)) {
Assert::assertEquals($this->requestOptions['body'], $lastRequest->getInput());
Assert::assertStringContainsString(
'application/json',
(string)($lastRequest->getHeaders()['Content-Type'] ?? $lastRequest->getHeaders()['CONTENT_TYPE'] ?? '')
);
}
}
private function getParsedInputFromRequest(RequestInfo $requestInfo): array {
$headers = $requestInfo->getHeaders();
$contentType = $headers['Content-Type'] ?? $headers['CONTENT_TYPE'] ?? '';
$input = $requestInfo->getInput();
if (str_contains((string)$contentType, 'application/json') || $this->isJson($input)) {
$decoded = json_decode($input, true);
if (is_array($decoded)) {
return $decoded;
}
}
return $requestInfo->getParsedInput() ?? [];
}
private function hasNestedPayload(array $payload): bool {
foreach ($payload as $value) {
if (is_array($value) || $value instanceof \stdClass) {
return true;
}
}
return false;
}
#[Given('set the response to:')]
public function setTheResponseTo(PyStringNode $response): void {
// Mock response to be equal to body of request
$this->mockServer->setDefaultResponse(new MockWebServerResponse(
(string) $response
));
}
#[Given('set the response with :header header :value to:')]
public function setTheResponseWithHeaderTo(string $header, string $value, PyStringNode $response): void {
$this->mockServer->setDefaultResponse(new MockWebServerResponse(
(string) $response,
[$header => $value]
));
}
/**
* @inheritDoc
*/
#[\Override]
public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(TableNode $table): void {
$lastRequest = $this->getLastRequest();
$parsedInput = $this->getParsedInputFromRequest($lastRequest);
if ($this->hasNestedPayload($parsedInput)) {
$body = json_encode($parsedInput);
Assert::assertIsString($body);
$this->response = new Response(200, [], $body);
}
parent::theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues($table);
}
}