Proyectos de Subversion Moodle

Rev

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