You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
8.5 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. require __DIR__ . '/../../vendor/autoload.php';
  8. class CommentsContext implements \Behat\Behat\Context\Context {
  9. /** @var string */
  10. private $baseUrl;
  11. /** @var array */
  12. private $response;
  13. /** @var int */
  14. private $commentId;
  15. /** @var int */
  16. private $fileId;
  17. /**
  18. * @param string $baseUrl
  19. */
  20. public function __construct($baseUrl) {
  21. $this->baseUrl = $baseUrl;
  22. // in case of ci deployment we take the server url from the environment
  23. $testServerUrl = getenv('TEST_SERVER_URL');
  24. if ($testServerUrl !== false) {
  25. $this->baseUrl = substr($testServerUrl, 0, -5);
  26. }
  27. }
  28. /**
  29. * get a named entry from response instead of picking a random entry from values
  30. *
  31. * @param string $path
  32. *
  33. * @return array|string
  34. * @throws Exception
  35. */
  36. private function getValueFromNamedEntries(string $path, array $response): mixed {
  37. $next = '';
  38. if (str_contains($path, ' ')) {
  39. [$key, $next] = explode(' ', $path, 2);
  40. } else {
  41. $key = $path;
  42. }
  43. foreach ($response as $entry) {
  44. if ($entry['name'] === $key) {
  45. if ($next !== '') {
  46. return $this->getValueFromNamedEntries($next, $entry['value']);
  47. } else {
  48. return $entry['value'];
  49. }
  50. }
  51. }
  52. return null;
  53. }
  54. /** @AfterScenario */
  55. public function teardownScenario() {
  56. $client = new \GuzzleHttp\Client();
  57. try {
  58. $client->delete(
  59. $this->baseUrl . '/remote.php/webdav/myFileToComment.txt',
  60. [
  61. 'auth' => [
  62. 'user0',
  63. '123456',
  64. ],
  65. 'headers' => [
  66. 'Content-Type' => 'application/json',
  67. ],
  68. ]
  69. );
  70. } catch (\GuzzleHttp\Exception\ClientException $e) {
  71. $e->getResponse();
  72. }
  73. }
  74. /**
  75. * @param string $path
  76. * @return int
  77. */
  78. private function getFileIdForPath($path) {
  79. $url = $this->baseUrl . '/remote.php/webdav/' . $path;
  80. $context = stream_context_create([
  81. 'http' => [
  82. 'method' => 'PROPFIND',
  83. 'header' => "Authorization: Basic dXNlcjA6MTIzNDU2\r\nContent-Type: application/x-www-form-urlencoded",
  84. 'content' => '<?xml version="1.0"?>
  85. <d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
  86. <d:prop>
  87. <oc:fileid />
  88. </d:prop>
  89. </d:propfind>'
  90. ]
  91. ]);
  92. $response = file_get_contents($url, false, $context);
  93. preg_match_all('/\<oc:fileid\>(.*)\<\/oc:fileid\>/', $response, $matches);
  94. return (int)$matches[1][0];
  95. }
  96. /**
  97. * @When :user posts a comment with content :content on the file named :fileName it should return :statusCode
  98. * @param string $user
  99. * @param string $content
  100. * @param string $fileName
  101. * @param int $statusCode
  102. * @throws \Exception
  103. */
  104. public function postsACommentWithContentOnTheFileNamedItShouldReturn($user, $content, $fileName, $statusCode) {
  105. $fileId = $this->getFileIdForPath($fileName);
  106. $this->fileId = (int)$fileId;
  107. $url = $this->baseUrl . '/remote.php/dav/comments/files/' . $fileId . '/';
  108. $client = new \GuzzleHttp\Client();
  109. try {
  110. $res = $client->post(
  111. $url,
  112. [
  113. 'body' => '{"actorId":"user0","actorDisplayName":"user0","actorType":"users","verb":"comment","message":"' . $content . '","creationDateTime":"Thu, 18 Feb 2016 17:04:18 GMT","objectType":"files"}',
  114. 'auth' => [
  115. $user,
  116. '123456',
  117. ],
  118. 'headers' => [
  119. 'Content-Type' => 'application/json',
  120. ],
  121. ]
  122. );
  123. } catch (\GuzzleHttp\Exception\ClientException $e) {
  124. $res = $e->getResponse();
  125. }
  126. if ($res->getStatusCode() !== (int)$statusCode) {
  127. throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
  128. }
  129. }
  130. /**
  131. * @Then As :user load all the comments of the file named :fileName it should return :statusCode
  132. * @param string $user
  133. * @param string $fileName
  134. * @param int $statusCode
  135. * @throws \Exception
  136. */
  137. public function asLoadloadAllTheCommentsOfTheFileNamedItShouldReturn($user, $fileName, $statusCode) {
  138. $fileId = $this->getFileIdForPath($fileName);
  139. $url = $this->baseUrl . '/remote.php/dav/comments/files/' . $fileId . '/';
  140. try {
  141. $client = new \GuzzleHttp\Client();
  142. $res = $client->request(
  143. 'REPORT',
  144. $url,
  145. [
  146. 'body' => '<?xml version="1.0" encoding="utf-8" ?>
  147. <oc:filter-comments xmlns:oc="http://owncloud.org/ns">
  148. <oc:limit>200</oc:limit>
  149. <oc:offset>0</oc:offset>
  150. </oc:filter-comments>
  151. ',
  152. 'auth' => [
  153. $user,
  154. '123456',
  155. ],
  156. 'headers' => [
  157. 'Content-Type' => 'application/json',
  158. ],
  159. ]
  160. );
  161. } catch (\GuzzleHttp\Exception\ClientException $e) {
  162. $res = $e->getResponse();
  163. }
  164. if ($res->getStatusCode() !== (int)$statusCode) {
  165. throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
  166. }
  167. if ($res->getStatusCode() === 207) {
  168. $service = new Sabre\Xml\Service();
  169. $this->response = $service->parse($res->getBody()->getContents());
  170. $this->commentId = (int) ($this->getValueFromNamedEntries('{DAV:}response {DAV:}propstat {DAV:}prop {http://owncloud.org/ns}id', $this->response ?? []) ?? 0);
  171. }
  172. }
  173. /**
  174. * @Given As :user sending :verb to :url with
  175. * @param string $user
  176. * @param string $verb
  177. * @param string $url
  178. * @param \Behat\Gherkin\Node\TableNode $body
  179. * @throws \Exception
  180. */
  181. public function asUserSendingToWith($user, $verb, $url, \Behat\Gherkin\Node\TableNode $body) {
  182. $client = new \GuzzleHttp\Client();
  183. $options = [];
  184. $options['auth'] = [$user, '123456'];
  185. $fd = $body->getRowsHash();
  186. $options['form_params'] = $fd;
  187. $options['headers'] = [
  188. 'OCS-APIREQUEST' => 'true',
  189. ];
  190. $client->request($verb, $this->baseUrl . '/ocs/v1.php/' . $url, $options);
  191. }
  192. /**
  193. * @Then As :user delete the created comment it should return :statusCode
  194. * @param string $user
  195. * @param int $statusCode
  196. * @throws \Exception
  197. */
  198. public function asDeleteTheCreatedCommentItShouldReturn($user, $statusCode) {
  199. $url = $this->baseUrl . '/remote.php/dav/comments/files/' . $this->fileId . '/' . $this->commentId;
  200. $client = new \GuzzleHttp\Client();
  201. try {
  202. $res = $client->delete(
  203. $url,
  204. [
  205. 'auth' => [
  206. $user,
  207. '123456',
  208. ],
  209. 'headers' => [
  210. 'Content-Type' => 'application/json',
  211. ],
  212. ]
  213. );
  214. } catch (\GuzzleHttp\Exception\ClientException $e) {
  215. $res = $e->getResponse();
  216. }
  217. if ($res->getStatusCode() !== (int)$statusCode) {
  218. throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
  219. }
  220. }
  221. /**
  222. * @Then the response should contain a property :key with value :value
  223. * @param string $key
  224. * @param string $value
  225. * @throws \Exception
  226. */
  227. public function theResponseShouldContainAPropertyWithValue($key, $value) {
  228. // $keys = $this->response[0]['value'][1]['value'][0]['value'];
  229. $keys = $this->getValueFromNamedEntries('{DAV:}response {DAV:}propstat {DAV:}prop', $this->response);
  230. $found = false;
  231. foreach ($keys as $singleKey) {
  232. if ($singleKey['name'] === '{http://owncloud.org/ns}' . substr($key, 3)) {
  233. if ($singleKey['value'] === $value) {
  234. $found = true;
  235. }
  236. }
  237. }
  238. if ($found === false) {
  239. throw new \Exception("Cannot find property $key with $value");
  240. }
  241. }
  242. /**
  243. * @Then the response should contain only :number comments
  244. * @param int $number
  245. * @throws \Exception
  246. */
  247. public function theResponseShouldContainOnlyComments($number) {
  248. $count = 0;
  249. if ($this->response !== null) {
  250. $count = count($this->response);
  251. }
  252. if ($count !== (int)$number) {
  253. throw new \Exception("Found more comments than $number (" . $count . ")");
  254. }
  255. }
  256. /**
  257. * @Then As :user edit the last created comment and set text to :text it should return :statusCode
  258. * @param string $user
  259. * @param string $text
  260. * @param int $statusCode
  261. * @throws \Exception
  262. */
  263. public function asEditTheLastCreatedCommentAndSetTextToItShouldReturn($user, $text, $statusCode) {
  264. $client = new \GuzzleHttp\Client();
  265. $options = [];
  266. $options['auth'] = [$user, '123456'];
  267. $options['body'] = '<?xml version="1.0"?>
  268. <d:propertyupdate xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
  269. <d:set>
  270. <d:prop>
  271. <oc:message>' . $text . '</oc:message>
  272. </d:prop>
  273. </d:set>
  274. </d:propertyupdate>';
  275. try {
  276. $res = $client->request('PROPPATCH', $this->baseUrl . '/remote.php/dav/comments/files/' . $this->fileId . '/' . $this->commentId, $options);
  277. } catch (\GuzzleHttp\Exception\ClientException $e) {
  278. $res = $e->getResponse();
  279. }
  280. if ($res->getStatusCode() !== (int)$statusCode) {
  281. throw new \Exception("Response status code was not $statusCode (" . $res->getStatusCode() . ")");
  282. }
  283. }
  284. }