CommentsContext.php 8.5 KB

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