Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace repository_nextcloud;
18
 
19
use testable_access_controlled_link_manager;
20
 
21
defined('MOODLE_INTERNAL') || die();
22
 
23
global $CFG;
24
require_once($CFG->libdir . '/webdavlib.php');
25
require_once($CFG->dirroot . '/repository/nextcloud/tests/fixtures/testable_access_controlled_link_manager.php');
26
 
27
/**
28
 * Class repository_nextcloud_testcase
29
 *
30
 * @package repository_nextcloud
31
 * @group repository_nextcloud
32
 * @copyright  2017 Project seminar (Learnweb, University of Münster)
33
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 */
1441 ariadna 35
final class access_controlled_link_manager_test extends \advanced_testcase {
1 efrain 36
 
37
    /** @var null|testable_access_controlled_link_manager a malleable variant of the access_controlled_link_manager. */
38
    public $linkmanager = null;
39
 
40
    /** @var null|\repository_nextcloud\ocs_client The ocs_client used to send requests. */
41
    public $ocsmockclient = null;
42
 
43
    /** @var null|\core\oauth2\client Mock oauth client for the system account. */
44
    private $oauthsystemmock = null;
45
 
46
    /** @var null|\core\oauth2\issuer which belongs to the repository_nextcloud object. */
47
    public $issuer = null;
48
 
49
    /** @var string system account username. */
50
    public $systemaccountusername;
51
 
52
    /**
53
     * SetUp to create an repository instance.
54
     */
55
    protected function setUp(): void {
1441 ariadna 56
        parent::setUp();
1 efrain 57
        $this->resetAfterTest(true);
58
 
59
        // Admin is necessary to create issuer object.
60
        $this->setAdminUser();
61
 
62
        $generator = $this->getDataGenerator()->get_plugin_generator('repository_nextcloud');
63
        $this->issuer = $generator->test_create_issuer();
64
        $generator->test_create_endpoints($this->issuer->get('id'));
65
 
66
        // Mock clients.
67
        $this->ocsmockclient = $this->getMockBuilder(ocs_client::class
68
        )->disableOriginalConstructor()->disableOriginalClone()->getMock();
69
        $this->oauthsystemmock = $this->getMockBuilder(\core\oauth2\client::class
70
        )->disableOriginalConstructor()->disableOriginalClone()->getMock();
71
        $systemwebdavclient = $this->getMockBuilder(\webdav_client::class
72
        )->disableOriginalConstructor()->disableOriginalClone()->getMock();
73
        $systemocsclient = $systemocsclient = $this->getMockBuilder(ocs_client::class
74
        )->disableOriginalConstructor()->disableOriginalClone()->getMock();
75
 
76
        // Pseudo system account user.
77
        $this->systemaccountusername = 'pseudouser';
78
        $record = new \stdClass();
79
        $record->issuerid = $this->issuer->get('id');
80
        $record->refreshtoken = 'pseudotoken';
81
        $record->grantedscopes = 'scopes';
82
        $record->email = '';
83
        $record->username = $this->systemaccountusername;
84
        $systemaccount = new \core\oauth2\system_account(0, $record);
85
        $systemaccount->create();
86
 
87
        $this->linkmanager = new testable_access_controlled_link_manager($this->ocsmockclient,
88
            $this->oauthsystemmock, $systemocsclient,
89
            $this->issuer, 'Nextcloud', $systemwebdavclient);
90
 
91
    }
92
 
93
    /**
94
     * Function to test the private function create_share_user_sysaccount.
95
     */
11 efrain 96
    public function test_create_share_user_sysaccount_user_shares(): void {
1 efrain 97
        $params = [
98
            'path' => "/ambient.txt",
99
            'shareType' => \repository_nextcloud\ocs_client::SHARE_TYPE_USER,
100
            'publicUpload' => false,
101
            'shareWith' => $this->systemaccountusername,
102
            'permissions' => \repository_nextcloud\ocs_client::SHARE_PERMISSION_READ,
103
        ];
104
        $expectedresponse = <<<XML
105
<?xml version="1.0"?>
106
<ocs>
107
 <meta>
108
  <status>ok</status>
109
  <statuscode>100</statuscode>
110
  <message/>
111
 </meta>
112
 <data>
113
  <id>207</id>
114
  <share_type>0</share_type>
115
  <uid_owner>user1</uid_owner>
116
  <displayname_owner>user1</displayname_owner>
117
  <permissions>19</permissions>
118
  <stime>1511532198</stime>
119
  <parent/>
120
  <expiration/>
121
  <token/>
122
  <uid_file_owner>user1</uid_file_owner>
123
  <displayname_file_owner>user1</displayname_file_owner>
124
  <path>/ambient.txt</path>
125
  <item_type>file</item_type>
126
  <mimetype>text/plain</mimetype>
127
  <storage_id>home::user1</storage_id>
128
  <storage>3</storage>
129
  <item_source>545</item_source>
130
  <file_source>545</file_source>
131
  <file_parent>20</file_parent>
132
  <file_target>/ambient.txt</file_target>
133
  <share_with>tech</share_with>
134
  <share_with_displayname>tech</share_with_displayname>
135
  <mail_send>0</mail_send>
136
 </data>
137
</ocs>
138
XML;
139
        $this->ocsmockclient->expects($this->once())->method('call')->with('create_share', $params)->will(
140
            $this->returnValue($expectedresponse));
141
 
142
        $result = $this->linkmanager->create_share_user_sysaccount("/ambient.txt");
143
        $xml = simplexml_load_string($expectedresponse);
144
        $expected = array();
145
        $expected['statuscode'] = (int)$xml->meta->statuscode;
146
        $expected['shareid'] = (int)$xml->data->id;
147
        $expected['filetarget'] = (string)$xml->data[0]->file_target;
148
        $this->assertEquals($expected, $result);
149
    }
150
    /**
151
     * Test the delete_share_function. In case the request fails, the function throws an exception, however this
152
     * can not be tested in phpUnit since it is javascript.
153
     */
11 efrain 154
    public function test_delete_share_dataowner_sysaccount(): void {
1 efrain 155
        $shareid = 5;
156
        $deleteshareparams = [
157
            'share_id' => $shareid
158
        ];
159
        $returnxml = <<<XML
160
<?xml version="1.0"?>
161
<ocs>
162
    <meta>
163
    <status>ok</status>
164
    <statuscode>100</statuscode>
165
    <message/>
166
    </meta>
167
    <data/>
168
</ocs>
169
XML;
170
        $this->ocsmockclient->expects($this->once())->method('call')->with('delete_share', $deleteshareparams)->will(
171
            $this->returnValue($returnxml));
172
        $this->linkmanager->delete_share_dataowner_sysaccount($shareid, 'repository_nextcloud');
173
 
174
    }
175
 
176
    /**
177
     * Function which test that create folder path does return the adequate results (path and success).
178
     * Additionally mock checks whether the right params are passed to the corresponding functions.
179
     */
11 efrain 180
    public function test_create_folder_path_folders_are_not_created(): void {
1 efrain 181
 
182
        $mocks = $this->set_up_mocks_for_create_folder_path(true, 'somename');
183
        $this->set_private_property($mocks['mockclient'], 'systemwebdavclient', $this->linkmanager);
184
        $result = $this->linkmanager->create_folder_path_access_controlled_links($mocks['mockcontext'], "mod_resource",
185
            'content', 0);
186
        $this->assertEquals('/somename (ctx )/mod_resource/content/0', $result);
187
    }
188
    /**
189
     * Function which test that create folder path does return the adequate results (path and success).
190
     * Additionally mock checks whether the right params are passed to the corresponding functions.
191
     */
11 efrain 192
    public function test_create_folder_path_folders_are_created(): void {
1 efrain 193
 
194
        // In Context is okay, number of context counts for number of iterations.
195
        $mocks = $this->set_up_mocks_for_create_folder_path(false, 'somename/withslash', true, 201);
196
        $this->set_private_property($mocks['mockclient'], 'systemwebdavclient', $this->linkmanager);
197
        $result = $this->linkmanager->create_folder_path_access_controlled_links($mocks['mockcontext'], "mod_resource",
198
            'content', 0);
199
        $this->assertEquals('/somenamewithslash (ctx )/mod_resource/content/0', $result);
200
    }
201
    /**
202
     * Test whether the create_folder_path methode throws exception.
203
     */
11 efrain 204
    public function test_create_folder_path_folder_creation_fails(): void {
1 efrain 205
 
206
        $mocks = $this->set_up_mocks_for_create_folder_path(false, 'somename', true, 400);
207
        $this->set_private_property($mocks['mockclient'], 'systemwebdavclient', $this->linkmanager);
208
        $this->expectException(\repository_nextcloud\request_exception::class);
209
        $this->linkmanager->create_folder_path_access_controlled_links($mocks['mockcontext'], "mod_resource",
210
            'content', 0);
211
    }
212
 
213
    /**
214
     * Helper function to generate mocks for testing create folder path.
215
     * @param bool $returnisdir Return value mocking the result of invoking is_dir
216
     * @param bool $returnestedcontext Name of the folder that is simulated to be checked/created
217
     * @param bool $callmkcol Also mock creation of the folder
218
     * @param int $returnmkcol Return value mocking the result of invoking mkcol
219
     * @return array ['mockcontext' context_module mock, 'mockclient' => webdav client mock]
220
     */
221
    protected function set_up_mocks_for_create_folder_path($returnisdir, $returnestedcontext, $callmkcol = false,
222
                                                           $returnmkcol = 201) {
223
        $mockcontext = $this->createMock(\context_module::class);
224
        $mockclient = $this->getMockBuilder(\webdav_client::class
225
        )->disableOriginalConstructor()->disableOriginalClone()->getMock();
226
        $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav'));
227
        $webdavprefix = $parsedwebdavurl['path'];
228
        // Empty ctx 'id' expected because using code will not be able to access $ctx->id.
229
        $cleanedcontextname = clean_param($returnestedcontext, PARAM_FILE);
230
        $dirstring = $webdavprefix . '/' . $cleanedcontextname . ' (ctx )';
231
        $mockclient->expects($this->atMost(4))->method('is_dir')->with($this->logicalOr(
232
            $dirstring, $dirstring . '/mod_resource', $dirstring . '/mod_resource/content',
233
            $dirstring . '/mod_resource/content/0'))->willReturn($returnisdir);
234
        if ($callmkcol == true) {
235
            $mockclient->expects($this->atMost(4))->method('mkcol')->willReturn($returnmkcol);
236
        }
237
        $mockcontext->method('get_parent_contexts')->willReturn(array('1' => $mockcontext));
238
        $mockcontext->method('get_context_name')->willReturn($returnestedcontext);
239
 
240
        return array('mockcontext' => $mockcontext, 'mockclient' => $mockclient);
241
    }
242
 
243
    /**
244
     * Test whether the right methods from the webdavclient are called when the storage_folder is created.
245
     * 1. Directory already exist -> no further action needed.
246
     */
11 efrain 247
    public function test_create_storage_folder_success(): void {
1 efrain 248
        $mockwebdavclient = $this->createMock(\webdav_client::class);
249
        $url = $this->issuer->get_endpoint_url('webdav');
250
        $parsedwebdavurl = parse_url($url);
251
        $webdavprefix = $parsedwebdavurl['path'];
252
        $mockwebdavclient->expects($this->once())->method('open')->willReturn(true);
253
        $mockwebdavclient->expects($this->once())->method('is_dir')->with($webdavprefix . 'myname')->willReturn(true);
254
        $mockwebdavclient->expects($this->once())->method('close');
255
        $this->linkmanager->create_storage_folder('myname', $mockwebdavclient);
256
 
257
    }
258
    /**
259
     * Test whether the right methods from the webdavclient are called when the storage_folder is created.
260
     * 2. Directory does not exist. It is created with mkcol and returns a success.
261
     *
262
     */
11 efrain 263
    public function test_create_storage_folder_success_mkcol(): void {
1 efrain 264
        $mockwebdavclient = $this->createMock(\webdav_client::class);
265
        $url = $this->issuer->get_endpoint_url('webdav');
266
        $parsedwebdavurl = parse_url($url);
267
        $webdavprefix = $parsedwebdavurl['path'];
268
        $mockwebdavclient->expects($this->once())->method('open')->willReturn(true);
269
        $mockwebdavclient->expects($this->once())->method('is_dir')->with($webdavprefix . 'myname')->willReturn(false);
270
        $mockwebdavclient->expects($this->once())->method('mkcol')->with($webdavprefix . 'myname')->willReturn(201);
271
        $mockwebdavclient->expects($this->once())->method('close');
272
 
273
        $this->linkmanager->create_storage_folder('myname', $mockwebdavclient);
274
    }
275
    /**
276
     * Test whether the right methods from the webdavclient are called when the storage_folder is created.
277
     * 3. Request to create Folder fails.
278
     */
11 efrain 279
    public function test_create_storage_folder_failure(): void {
1 efrain 280
        $mockwebdavclient = $this->createMock(\webdav_client::class);
281
        $url = $this->issuer->get_endpoint_url('webdav');
282
        $parsedwebdavurl = parse_url($url);
283
        $webdavprefix = $parsedwebdavurl['path'];
284
        $mockwebdavclient->expects($this->once())->method('open')->willReturn(true);
285
        $mockwebdavclient->expects($this->once())->method('is_dir')->with($webdavprefix . 'myname')->willReturn(false);
286
        $mockwebdavclient->expects($this->once())->method('mkcol')->with($webdavprefix . 'myname')->willReturn(400);
287
 
288
        $this->expectException(\repository_nextcloud\request_exception::class);
289
        $this->linkmanager->create_storage_folder('myname', $mockwebdavclient);
290
    }
291
    /**
292
     * Test whether the webdav client gets the right params and whether function differentiates between move and copy.
293
     */
11 efrain 294
    public function test_transfer_file_to_path_copyfile(): void {
1 efrain 295
        // Initialize params.
296
        $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav'));
297
        $webdavprefix = $parsedwebdavurl['path'];
298
        $srcpath = 'sourcepath';
299
        $dstpath = "destinationpath/another/path";
300
 
301
        // Mock the Webdavclient and set expected methods.
302
        $systemwebdavclientmock = $this->createMock(\webdav_client::class);
303
        $systemwebdavclientmock->expects($this->once())->method('open')->willReturn(true);
304
        $systemwebdavclientmock->expects($this->once())->method('copy_file')->with($webdavprefix . $srcpath,
305
            $webdavprefix . $dstpath . '/' . $srcpath, true)->willReturn(201);
306
        $this->set_private_property($systemwebdavclientmock, 'systemwebdavclient', $this->linkmanager);
307
 
308
        // Call of function.
309
        $result = $this->linkmanager->transfer_file_to_path($srcpath, $dstpath, 'copy');
310
 
311
        $this->assertEquals(201, $result);
312
    }
313
    /**
314
     * Test whether the webdav client gets the right params and whether function handles overwrite.
315
     *
316
     * @covers \repository_nextcloud\access_controlled_link_manager::transfer_file_to_path
317
     */
11 efrain 318
    public function test_transfer_file_to_path_overwritefile(): void {
1 efrain 319
        // Initialize params.
320
        $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav'));
321
        $webdavprefix = $parsedwebdavurl['path'];
322
        $srcpath = 'sourcepath';
323
        $dstpath = "destinationpath/another/path";
324
 
325
        // Mock the Webdavclient and set expected methods.
326
        $systemwebdavclientmock = $this->createMock(\webdav_client::class);
327
        $systemwebdavclientmock->expects($this->once())->method('open')->willReturn(true);
328
        $systemwebdavclientmock->expects($this->once())->method('copy_file')->with($webdavprefix . $srcpath,
329
            $webdavprefix . $dstpath . '/' . $srcpath, true)->willReturn(204);
330
        $this->set_private_property($systemwebdavclientmock, 'systemwebdavclient', $this->linkmanager);
331
 
332
        // Call of function.
333
        $result = $this->linkmanager->transfer_file_to_path($srcpath, $dstpath, 'copy');
334
 
335
        $this->assertEquals(204, $result);
336
    }
337
    /**
338
     * This function tests whether the function transfer_file_to_path() moves or copies a given file to a given path
339
     * It tests whether the webdav_client gets the right parameter and whether function distinguishes between move and copy.
340
     *
341
     */
11 efrain 342
    public function test_transfer_file_to_path_copyfile_movefile(): void {
1 efrain 343
        // Initialize params.
344
        $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav'));
345
        $webdavprefix = $parsedwebdavurl['path'];
346
        $srcpath = 'sourcepath';
347
        $dstpath = "destinationpath/another/path";
348
 
349
        $systemwebdavclientmock = $this->createMock(\webdav_client::class);
350
 
351
        $systemwebdavclientmock->expects($this->once())->method('open')->willReturn(true);
352
        $this->set_private_property($systemwebdavclientmock, 'systemwebdavclient', $this->linkmanager);
353
        $webdavclientmock = $this->createMock(\webdav_client::class);
354
 
355
        $webdavclientmock->expects($this->once())->method('move')->with($webdavprefix . $srcpath,
356
            $webdavprefix . $dstpath . '/' . $srcpath, false)->willReturn(201);
357
        $result = $this->linkmanager->transfer_file_to_path($srcpath, $dstpath, 'move', $webdavclientmock);
358
        $this->assertEquals(201, $result);
359
    }
360
 
361
    /**
362
     * Test the get_shares_from path() function. This function extracts from an list of shares the share of a given user
363
     * (the username is a parameter in the function call) and returns the id. The test firstly test whether the right fileid
364
     * for user1 is extracted then for user2 and last but least whether an error is thrown if the user does not have a share.
365
     * @throws moodle_exception
366
     */
11 efrain 367
    public function test_get_shares_from_path(): void {
1 efrain 368
        $params = [
369
            'path' => '/Kernsystem/Kursbereich Miscellaneous/Kurs Example Course/Datei zet/mod_resource/content/0/picture.png',
370
            'reshares' => true
371
        ];
372
        $reference = new \stdClass();
373
        $reference->link = "/Kernsystem/Kursbereich Miscellaneous/Kurs Example Course/Datei zet/mod_resource/content/0/picture.png";
374
        $reference->name = "f\u00fcrdennis.png";
375
        $reference->usesystem = true;
376
        $expectedresponse = <<<XML
377
<?xml version="1.0"?>
378
<ocs>
379
 <meta>
380
  <status>ok</status>
381
  <statuscode>100</statuscode>
382
  <message/>
383
 </meta>
384
 <data>
385
  <element>
386
   <id>292</id>
387
   <share_type>0</share_type>
388
   <uid_owner>tech</uid_owner>
389
   <displayname_owner>tech</displayname_owner>
390
   <permissions>19</permissions>
391
   <stime>1515752494</stime>
392
   <parent/>
393
   <expiration/>
394
   <token/>
395
   <uid_file_owner>tech</uid_file_owner>
396
   <displayname_file_owner>tech</displayname_file_owner>
397
   <path>some/path/of/some/file.pdf</path>
398
   <item_type>file</item_type>
399
   <mimetype>image/png</mimetype>
400
   <storage_id>home::tech</storage_id>
401
   <storage>4</storage>
402
   <item_source>1085</item_source>
403
   <file_source>1085</file_source>
404
   <file_parent>1084</file_parent>
405
   <file_target>/fehler (3).png</file_target>
406
   <share_with>user1</share_with>
407
   <share_with_displayname>user1</share_with_displayname>
408
   <mail_send>0</mail_send>
409
  </element>
410
  <element>
411
   <id>293</id>
412
   <share_type>0</share_type>
413
   <uid_owner>tech</uid_owner>
414
   <displayname_owner>tech</displayname_owner>
415
   <permissions>19</permissions>
416
   <stime>1515752494</stime>
417
   <parent/>
418
   <expiration/>
419
   <token/>
420
   <uid_file_owner>tech</uid_file_owner>
421
   <displayname_file_owner>tech</displayname_file_owner>
422
   <path>some/path/of/some/file.pdf</path>
423
   <item_type>file</item_type>
424
   <mimetype>image/png</mimetype>
425
   <storage_id>home::tech</storage_id>
426
   <storage>4</storage>
427
   <item_source>1085</item_source>
428
   <file_source>1085</file_source>
429
   <file_parent>1084</file_parent>
430
   <file_target>/fehler (3).png</file_target>
431
   <share_with>user2</share_with>
432
   <share_with_displayname>user2</share_with_displayname>
433
   <mail_send>0</mail_send>
434
  </element>
435
 </data>
436
</ocs>
437
XML;
438
        $this->set_private_property($this->ocsmockclient, 'systemocsclient', $this->linkmanager);
439
 
440
        $this->ocsmockclient->expects($this->exactly(3))->method('call')->with('get_shares', $params)->will(
441
            $this->returnValue($expectedresponse));
442
        $xmlobjuser1 = (int) $this->linkmanager->get_shares_from_path($reference->link, 'user2');
443
        $xmlobjuser2 = (int) $this->linkmanager->get_shares_from_path($reference->link, 'user1');
444
 
445
        $this->assertEquals(293, $xmlobjuser1);
446
        $this->assertEquals(292, $xmlobjuser2);
447
 
448
        $this->expectException(\repository_nextcloud\request_exception::class);
449
 
450
        $this->expectExceptionMessage('A request to Nextcloud has failed. The requested file could not be accessed. Please ' .
451
            'check whether you have chosen a valid file and you are authenticated with the right account.');
452
        $this->linkmanager->get_shares_from_path($reference->link, 'user3');
453
 
454
    }
455
    /** Test whether the systemwebdav client is constructed correctly. Port is set to 443 in case of https, to 80 in
456
     * case of http and exception is thrown when endpoint does not exist.
457
     * @throws \repository_nextcloud\configuration_exception
458
     * @throws coding_exception
459
     */
11 efrain 460
    public function test_create_system_dav(): void {
1 efrain 461
        // Initialize mock and params.
462
        $fakeaccesstoken = new \stdClass();
463
        $fakeaccesstoken->token = "fake access token";
464
        // Use `atLeastOnce` instead of `exactly(2)` because it is only called a second time on dev systems that allow http://.
465
        $this->oauthsystemmock->expects($this->atLeastOnce())->method('get_accesstoken')->willReturn($fakeaccesstoken);
466
        $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav'));
467
 
468
        // Call function and create own client.
469
        $dav = $this->linkmanager->create_system_dav();
470
        $mydav = new \webdav_client($parsedwebdavurl['host'], '', '', 'bearer', 'ssl://',
471
            "fake access token", $parsedwebdavurl['path']);
472
        $mydav->port = 443;
473
        $mydav->debug = false;
474
        $this->assertEquals($mydav, $dav);
475
 
476
        // Deletes the old webdav endpoint and ...
477
        $this->delete_endpoints('webdav_endpoint');
478
        // Creates a new one which requires different ports.
479
        try {
480
            $endpoint = new \stdClass();
481
            $endpoint->name = "webdav_endpoint";
482
            $endpoint->url = 'http://www.default.test/webdav/index.php';
483
            $endpoint->issuerid = $this->issuer->get('id');
484
            \core\oauth2\api::create_endpoint($endpoint);
485
 
486
            // Call function and create own client.
487
            $dav = $this->linkmanager->create_system_dav();
488
            $mydav = new \webdav_client($parsedwebdavurl['host'], '', '', 'bearer', '',
489
                "fake access token");
490
            $mydav->port = 80;
491
            $mydav->debug = false;
492
            $this->assertEquals($mydav, $dav);
493
        } catch (core\invalid_persistent_exception $e) {
494
            // In some cases Moodle does not allow to create http connections. In those cases the exception
495
            // is catched here and the test are executed.
496
            $this->expectException(\core\invalid_persistent_exception::class);
497
            $this->linkmanager->create_system_dav();
498
        } finally {
499
 
500
            // Delte endpoints and ...
501
            $this->delete_endpoints('webdav_endpoint');
502
 
503
            // Do not insert new ones, therefore exception is thrown.
504
            $this->expectException(\repository_nextcloud\configuration_exception::class);
505
            $this->linkmanager->create_system_dav();
506
        }
507
    }
508
 
509
    /**
510
     * Tests the function get_share_information_from_shareid(). From a response with two element it is tested
511
     * whether the right file_target is extracted and lastly it is checked whether an error is thrown in case no suitable
512
     * element exists.
513
     * @throws \repository_nextcloud\request_exception
514
     * @throws coding_exception
515
     */
11 efrain 516
    public function test_get_share_information_from_shareid(): void {
1 efrain 517
        $params303 = [
518
            'share_id' => 303,
519
        ];
520
        $params302 = [
521
            'share_id' => 302,
522
        ];
523
        $expectedresponse = <<<XML
524
<?xml version="1.0"?>
525
<ocs>
526
 <meta>
527
  <status>ok</status>
528
  <statuscode>100</statuscode>
529
  <message/>
530
 </meta>
531
 <data>
532
  <element>
533
   <id>302</id>
534
   <share_type>0</share_type>
535
   <uid_owner>tech</uid_owner>
536
   <displayname_owner>tech</displayname_owner>
537
   <permissions>19</permissions>
538
   <stime>1516096325</stime>
539
   <parent/>
540
   <expiration/>
541
   <token/>
542
   <uid_file_owner>tech</uid_file_owner>
543
   <displayname_file_owner>tech</displayname_file_owner>
544
     <path>/some/target (2).png</path>
545
   <item_type>file</item_type>
546
   <mimetype>image/png</mimetype>
547
   <storage_id>shared::/some/target.png</storage_id>
548
   <storage>4</storage>
549
   <item_source>1125</item_source>
550
   <file_source>1125</file_source>
551
   <file_parent>20</file_parent>
552
   <file_target>/some/target.png</file_target>
553
   <share_with>user1</share_with>
554
   <share_with_displayname>user1</share_with_displayname>
555
   <mail_send>0</mail_send>
556
  </element>
557
  <element>
558
   <id>303</id>
559
   <share_type>0</share_type>
560
   <uid_owner>tech</uid_owner>
561
   <displayname_owner>tech</displayname_owner>
562
   <permissions>19</permissions>
563
   <stime>1516096325</stime>
564
   <parent/>
565
   <expiration/>
566
   <token/>
567
   <uid_file_owner>tech</uid_file_owner>
568
   <displayname_file_owner>tech</displayname_file_owner>
569
   <path>/some/target (2).pdf</path>
570
   <item_type>file</item_type>
571
   <mimetype>image/png</mimetype>
572
   <storage_id>shared::/some/target.pdf</storage_id>
573
   <storage>4</storage>
574
   <item_source>1125</item_source>
575
   <file_source>1125</file_source>
576
   <file_parent>20</file_parent>
577
   <file_target>/some/target.pdf</file_target>
578
   <share_with>user2</share_with>
579
   <share_with_displayname>user1</share_with_displayname>
580
   <mail_send>0</mail_send>
581
  </element>
582
 </data>
583
</ocs>
584
XML;
585
        $this->set_private_property($this->ocsmockclient, 'systemocsclient', $this->linkmanager);
586
 
587
        $this->ocsmockclient->expects($this->exactly(3))->method('call')->with('get_information_of_share',
588
            $this->logicalOr($params303, $params302))->will($this->returnValue($expectedresponse));
589
 
590
        // Test function for two different users. Setting the id is just a dummy value since always $expectedresponse ...
591
        // ... is returned.
592
        $filetarget = $this->linkmanager->get_share_information_from_shareid(303, 'user2');
593
        $this->assertEquals('/some/target.pdf', $filetarget);
594
 
595
        $filetarget = $this->linkmanager->get_share_information_from_shareid(302, 'user1');
596
        $this->assertEquals('/some/target.png', $filetarget);
597
 
598
        // Expect exception in case no suitable elemtn exist in the response.
599
        $this->expectException(\repository_nextcloud\request_exception::class);
600
        $this->expectExceptionMessage('A request to Nextcloud has failed. The requested file could not be accessed. Please ' .
601
            'check whether you have chosen a valid file and you are authenticated with the right account.');
602
        $this->linkmanager->get_share_information_from_shareid(302, 'user3');
603
    }
604
 
605
    /**
606
     * Helper method which inserts a value into a non-public field of an object.
607
     *
608
     * @param mixed $value mock value that will be inserted.
609
     * @param string $propertyname name of the private property.
610
     * @param object $class Instance that is being modified.
611
     * @return ReflectionProperty the resulting reflection property.
612
     */
613
    protected function set_private_property($value, $propertyname, $class) {
614
        $refclient = new \ReflectionClass($class);
615
        $private = $refclient->getProperty($propertyname);
616
        $private->setValue($class, $value);
617
        return $private;
618
    }
619
    /**
620
     * Helper method which gets a value from a non-public field of an object.
621
     *
622
     * @param string $propertyname name of the private property.
623
     * @param object $class Instance that is being modified.
624
     * @return mixed the resulting value.
625
     */
626
    protected function get_private_property($propertyname, $class) {
627
        $refclient = new \ReflectionClass($class);
628
        $private = $refclient->getProperty($propertyname);
629
        $property = $private->getValue($private);
630
        return $property;
631
    }
632
    /**
633
     * Deletes all endpoint with the given name.
634
     * @param string $endpointname
635
     * @return array|null
636
     * @throws moodle_exception
637
     */
638
    protected function delete_endpoints($endpointname) {
639
        $endpoints = \core\oauth2\api::get_endpoints($this->issuer);
640
        $arrayofids = array();
641
        foreach ($endpoints as $endpoint) {
642
            $name = $endpoint->get('name');
643
            if ($name === $endpointname) {
644
                $arrayofids[$endpoint->get('id')] = $endpoint->get('id');
645
            }
646
        }
647
        if (empty($arrayofids)) {
648
            return;
649
        }
650
        foreach ($arrayofids as $id) {
651
            \core\oauth2\api::delete_endpoint($id);
652
        }
653
    }
654
 
655
}