Completed
Push — master ( adc201...206b61 )
by
unknown
35:27 queued 10s
created
tests/lib/Lockdown/Filesystem/NoFSTest.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -16,32 +16,32 @@
 block discarded – undo
16 16
 
17 17
 #[\PHPUnit\Framework\Attributes\Group('DB')]
18 18
 class NoFSTest extends \Test\TestCase {
19
-	use UserTrait;
20
-
21
-	protected function tearDown(): void {
22
-		$token = new PublicKeyToken();
23
-		$token->setScope([
24
-			IToken::SCOPE_FILESYSTEM => true
25
-		]);
26
-		Server::get('LockdownManager')->setToken($token);
27
-		parent::tearDown();
28
-	}
29
-
30
-	protected function setUp(): void {
31
-		parent::setUp();
32
-		$token = new PublicKeyToken();
33
-		$token->setScope([
34
-			IToken::SCOPE_FILESYSTEM => false
35
-		]);
36
-
37
-		Server::get('LockdownManager')->setToken($token);
38
-		$this->createUser('foo', 'var');
39
-	}
40
-
41
-	public function testSetupFS(): void {
42
-		\OC_Util::tearDownFS();
43
-		\OC_Util::setupFS('foo');
44
-
45
-		$this->assertInstanceOf(NullStorage::class, Filesystem::getStorage('/foo/files'));
46
-	}
19
+    use UserTrait;
20
+
21
+    protected function tearDown(): void {
22
+        $token = new PublicKeyToken();
23
+        $token->setScope([
24
+            IToken::SCOPE_FILESYSTEM => true
25
+        ]);
26
+        Server::get('LockdownManager')->setToken($token);
27
+        parent::tearDown();
28
+    }
29
+
30
+    protected function setUp(): void {
31
+        parent::setUp();
32
+        $token = new PublicKeyToken();
33
+        $token->setScope([
34
+            IToken::SCOPE_FILESYSTEM => false
35
+        ]);
36
+
37
+        Server::get('LockdownManager')->setToken($token);
38
+        $this->createUser('foo', 'var');
39
+    }
40
+
41
+    public function testSetupFS(): void {
42
+        \OC_Util::tearDownFS();
43
+        \OC_Util::setupFS('foo');
44
+
45
+        $this->assertInstanceOf(NullStorage::class, Filesystem::getStorage('/foo/files'));
46
+    }
47 47
 }
Please login to merge, or discard this patch.
tests/lib/AppScriptSortTest.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -19,106 +19,106 @@
 block discarded – undo
19 19
  */
20 20
 #[\PHPUnit\Framework\Attributes\Group('DB')]
21 21
 class AppScriptSortTest extends \Test\TestCase {
22
-	private $logger;
23
-
24
-	protected function setUp(): void {
25
-		$this->logger = $this->getMockBuilder(LoggerInterface::class)
26
-			->disableOriginalConstructor()
27
-			->getMock();
28
-
29
-		parent::setUp();
30
-	}
31
-
32
-	public function testSort(): void {
33
-		$scripts = [
34
-			'first' => ['myFirstJSFile'],
35
-			'core' => [
36
-				'core/js/myFancyJSFile1',
37
-				'core/js/myFancyJSFile4',
38
-				'core/js/myFancyJSFile5',
39
-				'core/js/myFancyJSFile1',
40
-			],
41
-			'files' => ['files/js/myFancyJSFile2'],
42
-			'myApp5' => ['myApp5/js/myApp5JSFile'],
43
-			'myApp' => ['myApp/js/myFancyJSFile3'],
44
-			'myApp4' => ['myApp4/js/myApp4JSFile'],
45
-			'myApp3' => ['myApp3/js/myApp3JSFile'],
46
-			'myApp2' => ['myApp2/js/myApp2JSFile'],
47
-		];
48
-		$scriptDeps = [
49
-			'first' => new AppScriptDependency('first', ['core']),
50
-			'core' => new AppScriptDependency('core', ['core']),
51
-			'files' => new AppScriptDependency('files', ['core']),
52
-			'myApp5' => new AppScriptDependency('myApp5', ['myApp2']),
53
-			'myApp' => new AppScriptDependency('myApp', ['core']),
54
-			'myApp4' => new AppScriptDependency('myApp4', ['myApp3']),
55
-			'myApp3' => new AppScriptDependency('myApp3', ['myApp2']),
56
-			'myApp2' => new AppScriptDependency('myApp2', ['myApp']),
57
-		];
58
-
59
-		// No circular dependency is detected and logged as an error
60
-		$this->logger->expects(self::never())->method('error');
61
-
62
-		$scriptSort = new AppScriptSort($this->logger);
63
-		$sortedScripts = $scriptSort->sort($scripts, $scriptDeps);
64
-
65
-		$sortedScriptKeys = array_keys($sortedScripts);
66
-
67
-		// Core should appear first
68
-		$this->assertEquals(
69
-			0,
70
-			array_search('core', $sortedScriptKeys, true)
71
-		);
72
-
73
-		// Dependencies should appear before their children
74
-		$this->assertLessThan(
75
-			array_search('files', $sortedScriptKeys, true),
76
-			array_search('core', $sortedScriptKeys, true)
77
-		);
78
-		$this->assertLessThan(
79
-			array_search('myApp2', $sortedScriptKeys, true),
80
-			array_search('myApp', $sortedScriptKeys, true)
81
-		);
82
-		$this->assertLessThan(
83
-			array_search('myApp3', $sortedScriptKeys, true),
84
-			array_search('myApp2', $sortedScriptKeys, true)
85
-		);
86
-		$this->assertLessThan(
87
-			array_search('myApp4', $sortedScriptKeys, true),
88
-			array_search('myApp3', $sortedScriptKeys, true)
89
-		);
90
-		$this->assertLessThan(
91
-			array_search('myApp5', $sortedScriptKeys, true),
92
-			array_search('myApp2', $sortedScriptKeys, true)
93
-		);
94
-
95
-		// All apps still there
96
-		foreach ($scripts as $app => $_) {
97
-			$this->assertContains($app, $sortedScriptKeys);
98
-		}
99
-	}
100
-
101
-	public function testSortCircularDependency(): void {
102
-		$scripts = [
103
-			'circular' => ['circular/js/file1'],
104
-			'dependency' => ['dependency/js/file2'],
105
-		];
106
-		$scriptDeps = [
107
-			'circular' => new AppScriptDependency('circular', ['dependency']),
108
-			'dependency' => new AppScriptDependency('dependency', ['circular']),
109
-		];
110
-
111
-		// A circular dependency is detected and logged as an error
112
-		$this->logger->expects(self::once())->method('error');
113
-
114
-		$scriptSort = new AppScriptSort($this->logger);
115
-		$sortedScripts = $scriptSort->sort($scripts, $scriptDeps);
116
-
117
-		$sortedScriptKeys = array_keys($sortedScripts);
118
-
119
-		// All apps still there
120
-		foreach ($scripts as $app => $_) {
121
-			$this->assertContains($app, $sortedScriptKeys);
122
-		}
123
-	}
22
+    private $logger;
23
+
24
+    protected function setUp(): void {
25
+        $this->logger = $this->getMockBuilder(LoggerInterface::class)
26
+            ->disableOriginalConstructor()
27
+            ->getMock();
28
+
29
+        parent::setUp();
30
+    }
31
+
32
+    public function testSort(): void {
33
+        $scripts = [
34
+            'first' => ['myFirstJSFile'],
35
+            'core' => [
36
+                'core/js/myFancyJSFile1',
37
+                'core/js/myFancyJSFile4',
38
+                'core/js/myFancyJSFile5',
39
+                'core/js/myFancyJSFile1',
40
+            ],
41
+            'files' => ['files/js/myFancyJSFile2'],
42
+            'myApp5' => ['myApp5/js/myApp5JSFile'],
43
+            'myApp' => ['myApp/js/myFancyJSFile3'],
44
+            'myApp4' => ['myApp4/js/myApp4JSFile'],
45
+            'myApp3' => ['myApp3/js/myApp3JSFile'],
46
+            'myApp2' => ['myApp2/js/myApp2JSFile'],
47
+        ];
48
+        $scriptDeps = [
49
+            'first' => new AppScriptDependency('first', ['core']),
50
+            'core' => new AppScriptDependency('core', ['core']),
51
+            'files' => new AppScriptDependency('files', ['core']),
52
+            'myApp5' => new AppScriptDependency('myApp5', ['myApp2']),
53
+            'myApp' => new AppScriptDependency('myApp', ['core']),
54
+            'myApp4' => new AppScriptDependency('myApp4', ['myApp3']),
55
+            'myApp3' => new AppScriptDependency('myApp3', ['myApp2']),
56
+            'myApp2' => new AppScriptDependency('myApp2', ['myApp']),
57
+        ];
58
+
59
+        // No circular dependency is detected and logged as an error
60
+        $this->logger->expects(self::never())->method('error');
61
+
62
+        $scriptSort = new AppScriptSort($this->logger);
63
+        $sortedScripts = $scriptSort->sort($scripts, $scriptDeps);
64
+
65
+        $sortedScriptKeys = array_keys($sortedScripts);
66
+
67
+        // Core should appear first
68
+        $this->assertEquals(
69
+            0,
70
+            array_search('core', $sortedScriptKeys, true)
71
+        );
72
+
73
+        // Dependencies should appear before their children
74
+        $this->assertLessThan(
75
+            array_search('files', $sortedScriptKeys, true),
76
+            array_search('core', $sortedScriptKeys, true)
77
+        );
78
+        $this->assertLessThan(
79
+            array_search('myApp2', $sortedScriptKeys, true),
80
+            array_search('myApp', $sortedScriptKeys, true)
81
+        );
82
+        $this->assertLessThan(
83
+            array_search('myApp3', $sortedScriptKeys, true),
84
+            array_search('myApp2', $sortedScriptKeys, true)
85
+        );
86
+        $this->assertLessThan(
87
+            array_search('myApp4', $sortedScriptKeys, true),
88
+            array_search('myApp3', $sortedScriptKeys, true)
89
+        );
90
+        $this->assertLessThan(
91
+            array_search('myApp5', $sortedScriptKeys, true),
92
+            array_search('myApp2', $sortedScriptKeys, true)
93
+        );
94
+
95
+        // All apps still there
96
+        foreach ($scripts as $app => $_) {
97
+            $this->assertContains($app, $sortedScriptKeys);
98
+        }
99
+    }
100
+
101
+    public function testSortCircularDependency(): void {
102
+        $scripts = [
103
+            'circular' => ['circular/js/file1'],
104
+            'dependency' => ['dependency/js/file2'],
105
+        ];
106
+        $scriptDeps = [
107
+            'circular' => new AppScriptDependency('circular', ['dependency']),
108
+            'dependency' => new AppScriptDependency('dependency', ['circular']),
109
+        ];
110
+
111
+        // A circular dependency is detected and logged as an error
112
+        $this->logger->expects(self::once())->method('error');
113
+
114
+        $scriptSort = new AppScriptSort($this->logger);
115
+        $sortedScripts = $scriptSort->sort($scripts, $scriptDeps);
116
+
117
+        $sortedScriptKeys = array_keys($sortedScripts);
118
+
119
+        // All apps still there
120
+        foreach ($scripts as $app => $_) {
121
+            $this->assertContains($app, $sortedScriptKeys);
122
+        }
123
+    }
124 124
 }
Please login to merge, or discard this patch.
tests/lib/AppTest.php 1 patch
Indentation   +250 added lines, -250 removed lines patch added patch discarded remove patch
@@ -30,278 +30,278 @@
 block discarded – undo
30 30
  */
31 31
 #[\PHPUnit\Framework\Attributes\Group('DB')]
32 32
 class AppTest extends \Test\TestCase {
33
-	public const TEST_USER1 = 'user1';
34
-	public const TEST_USER2 = 'user2';
35
-	public const TEST_USER3 = 'user3';
36
-	public const TEST_GROUP1 = 'group1';
37
-	public const TEST_GROUP2 = 'group2';
33
+    public const TEST_USER1 = 'user1';
34
+    public const TEST_USER2 = 'user2';
35
+    public const TEST_USER3 = 'user3';
36
+    public const TEST_GROUP1 = 'group1';
37
+    public const TEST_GROUP2 = 'group2';
38 38
 
39
-	/**
40
-	 * Tests that the app order is correct
41
-	 */
42
-	public function testGetEnabledAppsIsSorted(): void {
43
-		$apps = \OC_App::getEnabledApps();
44
-		// copy array
45
-		$sortedApps = $apps;
46
-		sort($sortedApps);
47
-		// 'files' is always on top
48
-		unset($sortedApps[array_search('files', $sortedApps)]);
49
-		array_unshift($sortedApps, 'files');
50
-		$this->assertEquals($sortedApps, $apps);
51
-	}
39
+    /**
40
+     * Tests that the app order is correct
41
+     */
42
+    public function testGetEnabledAppsIsSorted(): void {
43
+        $apps = \OC_App::getEnabledApps();
44
+        // copy array
45
+        $sortedApps = $apps;
46
+        sort($sortedApps);
47
+        // 'files' is always on top
48
+        unset($sortedApps[array_search('files', $sortedApps)]);
49
+        array_unshift($sortedApps, 'files');
50
+        $this->assertEquals($sortedApps, $apps);
51
+    }
52 52
 
53
-	/**
54
-	 * Providers for the app config values
55
-	 */
56
-	public static function appConfigValuesProvider(): array {
57
-		return [
58
-			// logged in user1
59
-			[
60
-				self::TEST_USER1,
61
-				[
62
-					'files',
63
-					'app1',
64
-					'app3',
65
-					'appforgroup1',
66
-					'appforgroup12',
67
-					'cloud_federation_api',
68
-					'dav',
69
-					'federatedfilesharing',
70
-					'lookup_server_connector',
71
-					'oauth2',
72
-					'profile',
73
-					'provisioning_api',
74
-					'settings',
75
-					'theming',
76
-					'twofactor_backupcodes',
77
-					'viewer',
78
-					'workflowengine',
79
-				],
80
-				false
81
-			],
82
-			// logged in user2
83
-			[
84
-				self::TEST_USER2,
85
-				[
86
-					'files',
87
-					'app1',
88
-					'app3',
89
-					'appforgroup12',
90
-					'appforgroup2',
91
-					'cloud_federation_api',
92
-					'dav',
93
-					'federatedfilesharing',
94
-					'lookup_server_connector',
95
-					'oauth2',
96
-					'profile',
97
-					'provisioning_api',
98
-					'settings',
99
-					'theming',
100
-					'twofactor_backupcodes',
101
-					'viewer',
102
-					'workflowengine',
103
-				],
104
-				false
105
-			],
106
-			// logged in user3
107
-			[
108
-				self::TEST_USER3,
109
-				[
110
-					'files',
111
-					'app1',
112
-					'app3',
113
-					'appforgroup1',
114
-					'appforgroup12',
115
-					'appforgroup2',
116
-					'cloud_federation_api',
117
-					'dav',
118
-					'federatedfilesharing',
119
-					'lookup_server_connector',
120
-					'oauth2',
121
-					'profile',
122
-					'provisioning_api',
123
-					'settings',
124
-					'theming',
125
-					'twofactor_backupcodes',
126
-					'viewer',
127
-					'workflowengine',
128
-				],
129
-				false
130
-			],
131
-			//  no user, returns all apps
132
-			[
133
-				null,
134
-				[
135
-					'files',
136
-					'app1',
137
-					'app3',
138
-					'appforgroup1',
139
-					'appforgroup12',
140
-					'appforgroup2',
141
-					'cloud_federation_api',
142
-					'dav',
143
-					'federatedfilesharing',
144
-					'lookup_server_connector',
145
-					'oauth2',
146
-					'profile',
147
-					'provisioning_api',
148
-					'settings',
149
-					'theming',
150
-					'twofactor_backupcodes',
151
-					'viewer',
152
-					'workflowengine',
153
-				],
154
-				false,
155
-			],
156
-			//  user given, but ask for all
157
-			[
158
-				self::TEST_USER1,
159
-				[
160
-					'files',
161
-					'app1',
162
-					'app3',
163
-					'appforgroup1',
164
-					'appforgroup12',
165
-					'appforgroup2',
166
-					'cloud_federation_api',
167
-					'dav',
168
-					'federatedfilesharing',
169
-					'lookup_server_connector',
170
-					'oauth2',
171
-					'profile',
172
-					'provisioning_api',
173
-					'settings',
174
-					'theming',
175
-					'twofactor_backupcodes',
176
-					'viewer',
177
-					'workflowengine',
178
-				],
179
-				true,
180
-			],
181
-		];
182
-	}
53
+    /**
54
+     * Providers for the app config values
55
+     */
56
+    public static function appConfigValuesProvider(): array {
57
+        return [
58
+            // logged in user1
59
+            [
60
+                self::TEST_USER1,
61
+                [
62
+                    'files',
63
+                    'app1',
64
+                    'app3',
65
+                    'appforgroup1',
66
+                    'appforgroup12',
67
+                    'cloud_federation_api',
68
+                    'dav',
69
+                    'federatedfilesharing',
70
+                    'lookup_server_connector',
71
+                    'oauth2',
72
+                    'profile',
73
+                    'provisioning_api',
74
+                    'settings',
75
+                    'theming',
76
+                    'twofactor_backupcodes',
77
+                    'viewer',
78
+                    'workflowengine',
79
+                ],
80
+                false
81
+            ],
82
+            // logged in user2
83
+            [
84
+                self::TEST_USER2,
85
+                [
86
+                    'files',
87
+                    'app1',
88
+                    'app3',
89
+                    'appforgroup12',
90
+                    'appforgroup2',
91
+                    'cloud_federation_api',
92
+                    'dav',
93
+                    'federatedfilesharing',
94
+                    'lookup_server_connector',
95
+                    'oauth2',
96
+                    'profile',
97
+                    'provisioning_api',
98
+                    'settings',
99
+                    'theming',
100
+                    'twofactor_backupcodes',
101
+                    'viewer',
102
+                    'workflowengine',
103
+                ],
104
+                false
105
+            ],
106
+            // logged in user3
107
+            [
108
+                self::TEST_USER3,
109
+                [
110
+                    'files',
111
+                    'app1',
112
+                    'app3',
113
+                    'appforgroup1',
114
+                    'appforgroup12',
115
+                    'appforgroup2',
116
+                    'cloud_federation_api',
117
+                    'dav',
118
+                    'federatedfilesharing',
119
+                    'lookup_server_connector',
120
+                    'oauth2',
121
+                    'profile',
122
+                    'provisioning_api',
123
+                    'settings',
124
+                    'theming',
125
+                    'twofactor_backupcodes',
126
+                    'viewer',
127
+                    'workflowengine',
128
+                ],
129
+                false
130
+            ],
131
+            //  no user, returns all apps
132
+            [
133
+                null,
134
+                [
135
+                    'files',
136
+                    'app1',
137
+                    'app3',
138
+                    'appforgroup1',
139
+                    'appforgroup12',
140
+                    'appforgroup2',
141
+                    'cloud_federation_api',
142
+                    'dav',
143
+                    'federatedfilesharing',
144
+                    'lookup_server_connector',
145
+                    'oauth2',
146
+                    'profile',
147
+                    'provisioning_api',
148
+                    'settings',
149
+                    'theming',
150
+                    'twofactor_backupcodes',
151
+                    'viewer',
152
+                    'workflowengine',
153
+                ],
154
+                false,
155
+            ],
156
+            //  user given, but ask for all
157
+            [
158
+                self::TEST_USER1,
159
+                [
160
+                    'files',
161
+                    'app1',
162
+                    'app3',
163
+                    'appforgroup1',
164
+                    'appforgroup12',
165
+                    'appforgroup2',
166
+                    'cloud_federation_api',
167
+                    'dav',
168
+                    'federatedfilesharing',
169
+                    'lookup_server_connector',
170
+                    'oauth2',
171
+                    'profile',
172
+                    'provisioning_api',
173
+                    'settings',
174
+                    'theming',
175
+                    'twofactor_backupcodes',
176
+                    'viewer',
177
+                    'workflowengine',
178
+                ],
179
+                true,
180
+            ],
181
+        ];
182
+    }
183 183
 
184
-	/**
185
-	 * Test enabled apps
186
-	 */
187
-	#[\PHPUnit\Framework\Attributes\DataProvider('appConfigValuesProvider')]
188
-	public function testEnabledApps($user, $expectedApps, $forceAll): void {
189
-		$userManager = Server::get(IUserManager::class);
190
-		$groupManager = Server::get(IGroupManager::class);
191
-		$user1 = $userManager->createUser(self::TEST_USER1, 'NotAnEasyPassword123456+');
192
-		$user2 = $userManager->createUser(self::TEST_USER2, 'NotAnEasyPassword123456_');
193
-		$user3 = $userManager->createUser(self::TEST_USER3, 'NotAnEasyPassword123456?');
184
+    /**
185
+     * Test enabled apps
186
+     */
187
+    #[\PHPUnit\Framework\Attributes\DataProvider('appConfigValuesProvider')]
188
+    public function testEnabledApps($user, $expectedApps, $forceAll): void {
189
+        $userManager = Server::get(IUserManager::class);
190
+        $groupManager = Server::get(IGroupManager::class);
191
+        $user1 = $userManager->createUser(self::TEST_USER1, 'NotAnEasyPassword123456+');
192
+        $user2 = $userManager->createUser(self::TEST_USER2, 'NotAnEasyPassword123456_');
193
+        $user3 = $userManager->createUser(self::TEST_USER3, 'NotAnEasyPassword123456?');
194 194
 
195
-		$group1 = $groupManager->createGroup(self::TEST_GROUP1);
196
-		$group1->addUser($user1);
197
-		$group1->addUser($user3);
198
-		$group2 = $groupManager->createGroup(self::TEST_GROUP2);
199
-		$group2->addUser($user2);
200
-		$group2->addUser($user3);
195
+        $group1 = $groupManager->createGroup(self::TEST_GROUP1);
196
+        $group1->addUser($user1);
197
+        $group1->addUser($user3);
198
+        $group2 = $groupManager->createGroup(self::TEST_GROUP2);
199
+        $group2->addUser($user2);
200
+        $group2->addUser($user3);
201 201
 
202
-		\OC_User::setUserId($user);
202
+        \OC_User::setUserId($user);
203 203
 
204
-		$this->setupAppConfigMock()->expects($this->once())
205
-			->method('searchValues')
206
-			->willReturn(
207
-				[
208
-					'app3' => 'yes',
209
-					'app2' => 'no',
210
-					'app1' => 'yes',
211
-					'appforgroup1' => '["group1"]',
212
-					'appforgroup2' => '["group2"]',
213
-					'appforgroup12' => '["group2","group1"]',
214
-				]
215
-			);
204
+        $this->setupAppConfigMock()->expects($this->once())
205
+            ->method('searchValues')
206
+            ->willReturn(
207
+                [
208
+                    'app3' => 'yes',
209
+                    'app2' => 'no',
210
+                    'app1' => 'yes',
211
+                    'appforgroup1' => '["group1"]',
212
+                    'appforgroup2' => '["group2"]',
213
+                    'appforgroup12' => '["group2","group1"]',
214
+                ]
215
+            );
216 216
 
217
-		$apps = \OC_App::getEnabledApps(false, $forceAll);
217
+        $apps = \OC_App::getEnabledApps(false, $forceAll);
218 218
 
219
-		$this->restoreAppConfig();
220
-		\OC_User::setUserId(null);
219
+        $this->restoreAppConfig();
220
+        \OC_User::setUserId(null);
221 221
 
222
-		$user1->delete();
223
-		$user2->delete();
224
-		$user3->delete();
222
+        $user1->delete();
223
+        $user2->delete();
224
+        $user3->delete();
225 225
 
226
-		$group1->delete();
227
-		$group2->delete();
226
+        $group1->delete();
227
+        $group2->delete();
228 228
 
229
-		$this->assertEquals($expectedApps, $apps);
230
-	}
229
+        $this->assertEquals($expectedApps, $apps);
230
+    }
231 231
 
232
-	/**
233
-	 * Test isEnabledApps() with cache, not re-reading the list of
234
-	 * enabled apps more than once when a user is set.
235
-	 */
236
-	public function testEnabledAppsCache(): void {
237
-		$userManager = Server::get(IUserManager::class);
238
-		$user1 = $userManager->createUser(self::TEST_USER1, 'NotAnEasyPassword123456+');
232
+    /**
233
+     * Test isEnabledApps() with cache, not re-reading the list of
234
+     * enabled apps more than once when a user is set.
235
+     */
236
+    public function testEnabledAppsCache(): void {
237
+        $userManager = Server::get(IUserManager::class);
238
+        $user1 = $userManager->createUser(self::TEST_USER1, 'NotAnEasyPassword123456+');
239 239
 
240
-		\OC_User::setUserId(self::TEST_USER1);
240
+        \OC_User::setUserId(self::TEST_USER1);
241 241
 
242
-		$this->setupAppConfigMock()->expects($this->once())
243
-			->method('searchValues')
244
-			->willReturn(
245
-				[
246
-					'app3' => 'yes',
247
-					'app2' => 'no',
248
-				]
249
-			);
242
+        $this->setupAppConfigMock()->expects($this->once())
243
+            ->method('searchValues')
244
+            ->willReturn(
245
+                [
246
+                    'app3' => 'yes',
247
+                    'app2' => 'no',
248
+                ]
249
+            );
250 250
 
251
-		$apps = \OC_App::getEnabledApps();
252
-		$this->assertEquals(['files', 'app3', 'cloud_federation_api', 'dav', 'federatedfilesharing', 'lookup_server_connector', 'oauth2', 'profile', 'provisioning_api', 'settings', 'theming', 'twofactor_backupcodes', 'viewer', 'workflowengine'], $apps);
251
+        $apps = \OC_App::getEnabledApps();
252
+        $this->assertEquals(['files', 'app3', 'cloud_federation_api', 'dav', 'federatedfilesharing', 'lookup_server_connector', 'oauth2', 'profile', 'provisioning_api', 'settings', 'theming', 'twofactor_backupcodes', 'viewer', 'workflowengine'], $apps);
253 253
 
254
-		// mock should not be called again here
255
-		$apps = \OC_App::getEnabledApps();
256
-		$this->assertEquals(['files', 'app3', 'cloud_federation_api', 'dav', 'federatedfilesharing', 'lookup_server_connector', 'oauth2', 'profile', 'provisioning_api', 'settings', 'theming', 'twofactor_backupcodes', 'viewer', 'workflowengine'], $apps);
254
+        // mock should not be called again here
255
+        $apps = \OC_App::getEnabledApps();
256
+        $this->assertEquals(['files', 'app3', 'cloud_federation_api', 'dav', 'federatedfilesharing', 'lookup_server_connector', 'oauth2', 'profile', 'provisioning_api', 'settings', 'theming', 'twofactor_backupcodes', 'viewer', 'workflowengine'], $apps);
257 257
 
258
-		$this->restoreAppConfig();
259
-		\OC_User::setUserId(null);
258
+        $this->restoreAppConfig();
259
+        \OC_User::setUserId(null);
260 260
 
261
-		$user1->delete();
262
-	}
261
+        $user1->delete();
262
+    }
263 263
 
264 264
 
265
-	private function setupAppConfigMock() {
266
-		/** @var AppConfig|MockObject */
267
-		$appConfig = $this->getMockBuilder(AppConfig::class)
268
-			->onlyMethods(['searchValues'])
269
-			->setConstructorArgs([Server::get(IDBConnection::class)])
270
-			->disableOriginalConstructor()
271
-			->getMock();
265
+    private function setupAppConfigMock() {
266
+        /** @var AppConfig|MockObject */
267
+        $appConfig = $this->getMockBuilder(AppConfig::class)
268
+            ->onlyMethods(['searchValues'])
269
+            ->setConstructorArgs([Server::get(IDBConnection::class)])
270
+            ->disableOriginalConstructor()
271
+            ->getMock();
272 272
 
273
-		$this->registerAppConfig($appConfig);
274
-		return $appConfig;
275
-	}
273
+        $this->registerAppConfig($appConfig);
274
+        return $appConfig;
275
+    }
276 276
 
277
-	/**
278
-	 * Register an app config mock for testing purposes.
279
-	 *
280
-	 * @param IAppConfig $appConfig app config mock
281
-	 */
282
-	private function registerAppConfig(AppConfig $appConfig) {
283
-		$this->overwriteService(AppConfig::class, $appConfig);
284
-		$this->overwriteService(AppManager::class, new AppManager(
285
-			Server::get(IUserSession::class),
286
-			Server::get(IConfig::class),
287
-			Server::get(IGroupManager::class),
288
-			Server::get(ICacheFactory::class),
289
-			Server::get(IEventDispatcher::class),
290
-			Server::get(LoggerInterface::class),
291
-			Server::get(ServerVersion::class),
292
-			Server::get(ConfigManager::class),
293
-			Server::get(DependencyAnalyzer::class),
294
-		));
295
-	}
277
+    /**
278
+     * Register an app config mock for testing purposes.
279
+     *
280
+     * @param IAppConfig $appConfig app config mock
281
+     */
282
+    private function registerAppConfig(AppConfig $appConfig) {
283
+        $this->overwriteService(AppConfig::class, $appConfig);
284
+        $this->overwriteService(AppManager::class, new AppManager(
285
+            Server::get(IUserSession::class),
286
+            Server::get(IConfig::class),
287
+            Server::get(IGroupManager::class),
288
+            Server::get(ICacheFactory::class),
289
+            Server::get(IEventDispatcher::class),
290
+            Server::get(LoggerInterface::class),
291
+            Server::get(ServerVersion::class),
292
+            Server::get(ConfigManager::class),
293
+            Server::get(DependencyAnalyzer::class),
294
+        ));
295
+    }
296 296
 
297
-	/**
298
-	 * Restore the original app config service.
299
-	 */
300
-	private function restoreAppConfig() {
301
-		$this->restoreService(AppConfig::class);
302
-		$this->restoreService(AppManager::class);
297
+    /**
298
+     * Restore the original app config service.
299
+     */
300
+    private function restoreAppConfig() {
301
+        $this->restoreService(AppConfig::class);
302
+        $this->restoreService(AppManager::class);
303 303
 
304
-		// Remove the cache of the mocked apps list with a forceRefresh
305
-		\OC_App::getEnabledApps();
306
-	}
304
+        // Remove the cache of the mocked apps list with a forceRefresh
305
+        \OC_App::getEnabledApps();
306
+    }
307 307
 }
Please login to merge, or discard this patch.
tests/lib/HelperStorageTest.php 1 patch
Indentation   +228 added lines, -228 removed lines patch added patch discarded remove patch
@@ -22,232 +22,232 @@
 block discarded – undo
22 22
  */
23 23
 #[\PHPUnit\Framework\Attributes\Group('DB')]
24 24
 class HelperStorageTest extends \Test\TestCase {
25
-	use UserTrait;
26
-
27
-	/** @var string */
28
-	private $user;
29
-	/** @var Storage */
30
-	private $storageMock;
31
-	/** @var Storage */
32
-	private $storage;
33
-	private bool $savedQuotaIncludeExternalStorage;
34
-
35
-	protected function setUp(): void {
36
-		parent::setUp();
37
-
38
-		$this->user = $this->getUniqueID('user_');
39
-		$this->createUser($this->user, $this->user);
40
-		$this->savedQuotaIncludeExternalStorage = $this->getIncludeExternalStorage();
41
-
42
-		Filesystem::tearDown();
43
-		\OC_User::setUserId($this->user);
44
-		Filesystem::init($this->user, '/' . $this->user . '/files');
45
-
46
-		/** @var IMountManager $manager */
47
-		$manager = Server::get(IMountManager::class);
48
-		$manager->removeMount('/' . $this->user);
49
-
50
-		$this->storageMock = null;
51
-	}
52
-
53
-	protected function tearDown(): void {
54
-		$this->setIncludeExternalStorage($this->savedQuotaIncludeExternalStorage);
55
-		$this->user = null;
56
-
57
-		if ($this->storageMock) {
58
-			$this->storageMock->getCache()->clear();
59
-			$this->storageMock = null;
60
-		}
61
-		Filesystem::tearDown();
62
-
63
-		\OC_User::setUserId('');
64
-		Server::get(IConfig::class)->deleteAllUserValues($this->user);
65
-
66
-		parent::tearDown();
67
-	}
68
-
69
-	/**
70
-	 * Returns a storage mock that returns the given value as
71
-	 * free space
72
-	 *
73
-	 * @param int $freeSpace free space value
74
-	 * @return Storage
75
-	 */
76
-	private function getStorageMock($freeSpace = 12) {
77
-		$this->storageMock = $this->getMockBuilder(Temporary::class)
78
-			->onlyMethods(['free_space'])
79
-			->setConstructorArgs([[]])
80
-			->getMock();
81
-
82
-		$this->storageMock->expects($this->once())
83
-			->method('free_space')
84
-			->willReturn($freeSpace);
85
-		return $this->storageMock;
86
-	}
87
-
88
-	/**
89
-	 * Test getting the storage info
90
-	 */
91
-	public function testGetStorageInfo(): void {
92
-		$homeStorage = $this->getStorageMock(12);
93
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
94
-		$homeStorage->file_put_contents('test.txt', '01234');
95
-
96
-		$storageInfo = \OC_Helper::getStorageInfo('');
97
-		$this->assertEquals(12, $storageInfo['free']);
98
-		$this->assertEquals(5, $storageInfo['used']);
99
-		$this->assertEquals(17, $storageInfo['total']);
100
-	}
101
-
102
-	private function getIncludeExternalStorage(): bool {
103
-		$class = new \ReflectionClass(\OC_Helper::class);
104
-		$prop = $class->getProperty('quotaIncludeExternalStorage');
105
-		$prop->setAccessible(true);
106
-		return $prop->getValue(null) ?? false;
107
-	}
108
-
109
-	private function setIncludeExternalStorage(bool $include) {
110
-		$class = new \ReflectionClass(\OC_Helper::class);
111
-		$prop = $class->getProperty('quotaIncludeExternalStorage');
112
-		$prop->setAccessible(true);
113
-		$prop->setValue(null, $include);
114
-	}
115
-
116
-	/**
117
-	 * Test getting the storage info, ignoring extra mount points
118
-	 */
119
-	public function testGetStorageInfoExcludingExtStorage(): void {
120
-		$homeStorage = $this->getStorageMock(12);
121
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
122
-		$homeStorage->file_put_contents('test.txt', '01234');
123
-
124
-		$extStorage = new Temporary([]);
125
-		$extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq');
126
-		$extStorage->getScanner()->scan(''); // update root size
127
-
128
-		$this->setIncludeExternalStorage(false);
129
-
130
-		Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext');
131
-
132
-		$storageInfo = \OC_Helper::getStorageInfo('');
133
-		$this->assertEquals(12, $storageInfo['free']);
134
-		$this->assertEquals(5, $storageInfo['used']);
135
-		$this->assertEquals(17, $storageInfo['total']);
136
-	}
137
-
138
-	/**
139
-	 * Test getting the storage info, including extra mount points
140
-	 */
141
-	public function testGetStorageInfoIncludingExtStorage(): void {
142
-		$homeStorage = new Temporary([]);
143
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
144
-		$homeStorage->file_put_contents('test.txt', '01234');
145
-
146
-		$extStorage = new Temporary([]);
147
-		$extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq');
148
-		$extStorage->getScanner()->scan(''); // update root size
149
-
150
-		Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext');
151
-
152
-		$this->setIncludeExternalStorage(true);
153
-
154
-		$config = Server::get(IConfig::class);
155
-		$config->setUserValue($this->user, 'files', 'quota', '25');
156
-
157
-		$storageInfo = \OC_Helper::getStorageInfo('');
158
-		$this->assertEquals(3, $storageInfo['free']);
159
-		$this->assertEquals(22, $storageInfo['used']);
160
-		$this->assertEquals(25, $storageInfo['total']);
161
-
162
-		$config->setUserValue($this->user, 'files', 'quota', 'default');
163
-	}
164
-
165
-	/**
166
-	 * Test getting the storage info excluding extra mount points
167
-	 * when user has no quota set, even when quota ext storage option
168
-	 * was set
169
-	 */
170
-	public function testGetStorageInfoIncludingExtStorageWithNoUserQuota(): void {
171
-		$homeStorage = $this->getStorageMock(12);
172
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
173
-		$homeStorage->file_put_contents('test.txt', '01234');
174
-
175
-		$extStorage = new Temporary([]);
176
-		$extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq');
177
-		$extStorage->getScanner()->scan(''); // update root size
178
-
179
-		Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext');
180
-
181
-		$config = Server::get(IConfig::class);
182
-		$this->setIncludeExternalStorage(true);
183
-
184
-		$storageInfo = \OC_Helper::getStorageInfo('');
185
-		$this->assertEquals(12, $storageInfo['free'], '12 bytes free in home storage');
186
-		$this->assertEquals(22, $storageInfo['used'], '5 bytes of home storage and 17 bytes of the temporary storage are used');
187
-		$this->assertEquals(34, $storageInfo['total'], '5 bytes used and 12 bytes free in home storage as well as 17 bytes used in temporary storage');
188
-	}
189
-
190
-
191
-	/**
192
-	 * Test getting the storage info with quota enabled
193
-	 */
194
-	public function testGetStorageInfoWithQuota(): void {
195
-		$homeStorage = $this->getStorageMock(12);
196
-		$homeStorage->file_put_contents('test.txt', '01234');
197
-		$homeStorage = new Quota(
198
-			[
199
-				'storage' => $homeStorage,
200
-				'quota' => 7
201
-			]
202
-		);
203
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
204
-
205
-		$storageInfo = \OC_Helper::getStorageInfo('');
206
-		$this->assertEquals(2, $storageInfo['free']);
207
-		$this->assertEquals(5, $storageInfo['used']);
208
-		$this->assertEquals(7, $storageInfo['total']);
209
-	}
210
-
211
-	/**
212
-	 * Test getting the storage info when data exceeds quota
213
-	 */
214
-	public function testGetStorageInfoWhenSizeExceedsQuota(): void {
215
-		$homeStorage = $this->getStorageMock(12);
216
-		$homeStorage->file_put_contents('test.txt', '0123456789');
217
-		$homeStorage = new Quota(
218
-			[
219
-				'storage' => $homeStorage,
220
-				'quota' => 7
221
-			]
222
-		);
223
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
224
-
225
-		$storageInfo = \OC_Helper::getStorageInfo('');
226
-		$this->assertEquals(0, $storageInfo['free']);
227
-		$this->assertEquals(10, $storageInfo['used']);
228
-		// total = quota
229
-		$this->assertEquals(7, $storageInfo['total']);
230
-	}
231
-
232
-	/**
233
-	 * Test getting the storage info when the remaining
234
-	 * free storage space is less than the quota
235
-	 */
236
-	public function testGetStorageInfoWhenFreeSpaceLessThanQuota(): void {
237
-		$homeStorage = $this->getStorageMock(12);
238
-		$homeStorage->file_put_contents('test.txt', '01234');
239
-		$homeStorage = new Quota(
240
-			[
241
-				'storage' => $homeStorage,
242
-				'quota' => 18
243
-			]
244
-		);
245
-		Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
246
-
247
-		$storageInfo = \OC_Helper::getStorageInfo('');
248
-		$this->assertEquals(12, $storageInfo['free']);
249
-		$this->assertEquals(5, $storageInfo['used']);
250
-		// total = free + used (because quota > total)
251
-		$this->assertEquals(17, $storageInfo['total']);
252
-	}
25
+    use UserTrait;
26
+
27
+    /** @var string */
28
+    private $user;
29
+    /** @var Storage */
30
+    private $storageMock;
31
+    /** @var Storage */
32
+    private $storage;
33
+    private bool $savedQuotaIncludeExternalStorage;
34
+
35
+    protected function setUp(): void {
36
+        parent::setUp();
37
+
38
+        $this->user = $this->getUniqueID('user_');
39
+        $this->createUser($this->user, $this->user);
40
+        $this->savedQuotaIncludeExternalStorage = $this->getIncludeExternalStorage();
41
+
42
+        Filesystem::tearDown();
43
+        \OC_User::setUserId($this->user);
44
+        Filesystem::init($this->user, '/' . $this->user . '/files');
45
+
46
+        /** @var IMountManager $manager */
47
+        $manager = Server::get(IMountManager::class);
48
+        $manager->removeMount('/' . $this->user);
49
+
50
+        $this->storageMock = null;
51
+    }
52
+
53
+    protected function tearDown(): void {
54
+        $this->setIncludeExternalStorage($this->savedQuotaIncludeExternalStorage);
55
+        $this->user = null;
56
+
57
+        if ($this->storageMock) {
58
+            $this->storageMock->getCache()->clear();
59
+            $this->storageMock = null;
60
+        }
61
+        Filesystem::tearDown();
62
+
63
+        \OC_User::setUserId('');
64
+        Server::get(IConfig::class)->deleteAllUserValues($this->user);
65
+
66
+        parent::tearDown();
67
+    }
68
+
69
+    /**
70
+     * Returns a storage mock that returns the given value as
71
+     * free space
72
+     *
73
+     * @param int $freeSpace free space value
74
+     * @return Storage
75
+     */
76
+    private function getStorageMock($freeSpace = 12) {
77
+        $this->storageMock = $this->getMockBuilder(Temporary::class)
78
+            ->onlyMethods(['free_space'])
79
+            ->setConstructorArgs([[]])
80
+            ->getMock();
81
+
82
+        $this->storageMock->expects($this->once())
83
+            ->method('free_space')
84
+            ->willReturn($freeSpace);
85
+        return $this->storageMock;
86
+    }
87
+
88
+    /**
89
+     * Test getting the storage info
90
+     */
91
+    public function testGetStorageInfo(): void {
92
+        $homeStorage = $this->getStorageMock(12);
93
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
94
+        $homeStorage->file_put_contents('test.txt', '01234');
95
+
96
+        $storageInfo = \OC_Helper::getStorageInfo('');
97
+        $this->assertEquals(12, $storageInfo['free']);
98
+        $this->assertEquals(5, $storageInfo['used']);
99
+        $this->assertEquals(17, $storageInfo['total']);
100
+    }
101
+
102
+    private function getIncludeExternalStorage(): bool {
103
+        $class = new \ReflectionClass(\OC_Helper::class);
104
+        $prop = $class->getProperty('quotaIncludeExternalStorage');
105
+        $prop->setAccessible(true);
106
+        return $prop->getValue(null) ?? false;
107
+    }
108
+
109
+    private function setIncludeExternalStorage(bool $include) {
110
+        $class = new \ReflectionClass(\OC_Helper::class);
111
+        $prop = $class->getProperty('quotaIncludeExternalStorage');
112
+        $prop->setAccessible(true);
113
+        $prop->setValue(null, $include);
114
+    }
115
+
116
+    /**
117
+     * Test getting the storage info, ignoring extra mount points
118
+     */
119
+    public function testGetStorageInfoExcludingExtStorage(): void {
120
+        $homeStorage = $this->getStorageMock(12);
121
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
122
+        $homeStorage->file_put_contents('test.txt', '01234');
123
+
124
+        $extStorage = new Temporary([]);
125
+        $extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq');
126
+        $extStorage->getScanner()->scan(''); // update root size
127
+
128
+        $this->setIncludeExternalStorage(false);
129
+
130
+        Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext');
131
+
132
+        $storageInfo = \OC_Helper::getStorageInfo('');
133
+        $this->assertEquals(12, $storageInfo['free']);
134
+        $this->assertEquals(5, $storageInfo['used']);
135
+        $this->assertEquals(17, $storageInfo['total']);
136
+    }
137
+
138
+    /**
139
+     * Test getting the storage info, including extra mount points
140
+     */
141
+    public function testGetStorageInfoIncludingExtStorage(): void {
142
+        $homeStorage = new Temporary([]);
143
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
144
+        $homeStorage->file_put_contents('test.txt', '01234');
145
+
146
+        $extStorage = new Temporary([]);
147
+        $extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq');
148
+        $extStorage->getScanner()->scan(''); // update root size
149
+
150
+        Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext');
151
+
152
+        $this->setIncludeExternalStorage(true);
153
+
154
+        $config = Server::get(IConfig::class);
155
+        $config->setUserValue($this->user, 'files', 'quota', '25');
156
+
157
+        $storageInfo = \OC_Helper::getStorageInfo('');
158
+        $this->assertEquals(3, $storageInfo['free']);
159
+        $this->assertEquals(22, $storageInfo['used']);
160
+        $this->assertEquals(25, $storageInfo['total']);
161
+
162
+        $config->setUserValue($this->user, 'files', 'quota', 'default');
163
+    }
164
+
165
+    /**
166
+     * Test getting the storage info excluding extra mount points
167
+     * when user has no quota set, even when quota ext storage option
168
+     * was set
169
+     */
170
+    public function testGetStorageInfoIncludingExtStorageWithNoUserQuota(): void {
171
+        $homeStorage = $this->getStorageMock(12);
172
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
173
+        $homeStorage->file_put_contents('test.txt', '01234');
174
+
175
+        $extStorage = new Temporary([]);
176
+        $extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq');
177
+        $extStorage->getScanner()->scan(''); // update root size
178
+
179
+        Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext');
180
+
181
+        $config = Server::get(IConfig::class);
182
+        $this->setIncludeExternalStorage(true);
183
+
184
+        $storageInfo = \OC_Helper::getStorageInfo('');
185
+        $this->assertEquals(12, $storageInfo['free'], '12 bytes free in home storage');
186
+        $this->assertEquals(22, $storageInfo['used'], '5 bytes of home storage and 17 bytes of the temporary storage are used');
187
+        $this->assertEquals(34, $storageInfo['total'], '5 bytes used and 12 bytes free in home storage as well as 17 bytes used in temporary storage');
188
+    }
189
+
190
+
191
+    /**
192
+     * Test getting the storage info with quota enabled
193
+     */
194
+    public function testGetStorageInfoWithQuota(): void {
195
+        $homeStorage = $this->getStorageMock(12);
196
+        $homeStorage->file_put_contents('test.txt', '01234');
197
+        $homeStorage = new Quota(
198
+            [
199
+                'storage' => $homeStorage,
200
+                'quota' => 7
201
+            ]
202
+        );
203
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
204
+
205
+        $storageInfo = \OC_Helper::getStorageInfo('');
206
+        $this->assertEquals(2, $storageInfo['free']);
207
+        $this->assertEquals(5, $storageInfo['used']);
208
+        $this->assertEquals(7, $storageInfo['total']);
209
+    }
210
+
211
+    /**
212
+     * Test getting the storage info when data exceeds quota
213
+     */
214
+    public function testGetStorageInfoWhenSizeExceedsQuota(): void {
215
+        $homeStorage = $this->getStorageMock(12);
216
+        $homeStorage->file_put_contents('test.txt', '0123456789');
217
+        $homeStorage = new Quota(
218
+            [
219
+                'storage' => $homeStorage,
220
+                'quota' => 7
221
+            ]
222
+        );
223
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
224
+
225
+        $storageInfo = \OC_Helper::getStorageInfo('');
226
+        $this->assertEquals(0, $storageInfo['free']);
227
+        $this->assertEquals(10, $storageInfo['used']);
228
+        // total = quota
229
+        $this->assertEquals(7, $storageInfo['total']);
230
+    }
231
+
232
+    /**
233
+     * Test getting the storage info when the remaining
234
+     * free storage space is less than the quota
235
+     */
236
+    public function testGetStorageInfoWhenFreeSpaceLessThanQuota(): void {
237
+        $homeStorage = $this->getStorageMock(12);
238
+        $homeStorage->file_put_contents('test.txt', '01234');
239
+        $homeStorage = new Quota(
240
+            [
241
+                'storage' => $homeStorage,
242
+                'quota' => 18
243
+            ]
244
+        );
245
+        Filesystem::mount($homeStorage, [], '/' . $this->user . '/files');
246
+
247
+        $storageInfo = \OC_Helper::getStorageInfo('');
248
+        $this->assertEquals(12, $storageInfo['free']);
249
+        $this->assertEquals(5, $storageInfo['used']);
250
+        // total = free + used (because quota > total)
251
+        $this->assertEquals(17, $storageInfo['total']);
252
+    }
253 253
 }
Please login to merge, or discard this patch.
tests/lib/InfoXmlTest.php 1 patch
Indentation   +113 added lines, -113 removed lines patch added patch discarded remove patch
@@ -18,117 +18,117 @@
 block discarded – undo
18 18
  */
19 19
 #[\PHPUnit\Framework\Attributes\Group('DB')]
20 20
 class InfoXmlTest extends TestCase {
21
-	private IAppManager $appManager;
22
-
23
-	protected function setUp(): void {
24
-		parent::setUp();
25
-		$this->appManager = Server::get(IAppManager::class);
26
-	}
27
-
28
-	public static function dataApps(): array {
29
-		return [
30
-			['admin_audit'],
31
-			['comments'],
32
-			['dav'],
33
-			['encryption'],
34
-			['federatedfilesharing'],
35
-			['federation'],
36
-			['files'],
37
-			['files_external'],
38
-			['files_sharing'],
39
-			['files_trashbin'],
40
-			['files_versions'],
41
-			['provisioning_api'],
42
-			['systemtags'],
43
-			['theming'],
44
-			['settings'],
45
-			['twofactor_backupcodes'],
46
-			['updatenotification'],
47
-			['user_ldap'],
48
-			['workflowengine'],
49
-		];
50
-	}
51
-
52
-	/**
53
-	 * @param string $app
54
-	 */
55
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataApps')]
56
-	public function testClasses($app): void {
57
-		$appInfo = $this->appManager->getAppInfo($app);
58
-		$appPath = $this->appManager->getAppPath($app);
59
-		\OC_App::registerAutoloading($app, $appPath);
60
-
61
-		//Add the appcontainer
62
-		$applicationClassName = App::buildAppNamespace($app) . '\\AppInfo\\Application';
63
-		if (class_exists($applicationClassName)) {
64
-			$application = new $applicationClassName();
65
-			$this->addToAssertionCount(1);
66
-		} else {
67
-			$application = new App($app);
68
-			$this->addToAssertionCount(1);
69
-		}
70
-
71
-		if (isset($appInfo['background-jobs'])) {
72
-			foreach ($appInfo['background-jobs'] as $job) {
73
-				$this->assertTrue(class_exists($job), 'Asserting background job "' . $job . '" exists');
74
-				$this->assertInstanceOf($job, Server::get($job));
75
-			}
76
-		}
77
-
78
-		if (isset($appInfo['two-factor-providers'])) {
79
-			foreach ($appInfo['two-factor-providers'] as $provider) {
80
-				$this->assertTrue(class_exists($provider), 'Asserting two-factor providers "' . $provider . '" exists');
81
-				$this->assertInstanceOf($provider, Server::get($provider));
82
-			}
83
-		}
84
-
85
-		if (isset($appInfo['commands'])) {
86
-			foreach ($appInfo['commands'] as $command) {
87
-				$this->assertTrue(class_exists($command), 'Asserting command "' . $command . '" exists');
88
-				$this->assertInstanceOf($command, Server::get($command));
89
-			}
90
-		}
91
-
92
-		if (isset($appInfo['repair-steps']['pre-migration'])) {
93
-			foreach ($appInfo['repair-steps']['pre-migration'] as $migration) {
94
-				$this->assertTrue(class_exists($migration), 'Asserting pre-migration "' . $migration . '" exists');
95
-				$this->assertInstanceOf($migration, Server::get($migration));
96
-			}
97
-		}
98
-
99
-		if (isset($appInfo['repair-steps']['post-migration'])) {
100
-			foreach ($appInfo['repair-steps']['post-migration'] as $migration) {
101
-				$this->assertTrue(class_exists($migration), 'Asserting post-migration "' . $migration . '" exists');
102
-				$this->assertInstanceOf($migration, Server::get($migration));
103
-			}
104
-		}
105
-
106
-		if (isset($appInfo['repair-steps']['live-migration'])) {
107
-			foreach ($appInfo['repair-steps']['live-migration'] as $migration) {
108
-				$this->assertTrue(class_exists($migration), 'Asserting live-migration "' . $migration . '" exists');
109
-				$this->assertInstanceOf($migration, Server::get($migration));
110
-			}
111
-		}
112
-
113
-		if (isset($appInfo['repair-steps']['install'])) {
114
-			foreach ($appInfo['repair-steps']['install'] as $migration) {
115
-				$this->assertTrue(class_exists($migration), 'Asserting install-migration "' . $migration . '" exists');
116
-				$this->assertInstanceOf($migration, Server::get($migration));
117
-			}
118
-		}
119
-
120
-		if (isset($appInfo['repair-steps']['uninstall'])) {
121
-			foreach ($appInfo['repair-steps']['uninstall'] as $migration) {
122
-				$this->assertTrue(class_exists($migration), 'Asserting uninstall-migration "' . $migration . '" exists');
123
-				$this->assertInstanceOf($migration, Server::get($migration));
124
-			}
125
-		}
126
-
127
-		if (isset($appInfo['commands'])) {
128
-			foreach ($appInfo['commands'] as $command) {
129
-				$this->assertTrue(class_exists($command), 'Asserting command "' . $command . '"exists');
130
-				$this->assertInstanceOf($command, Server::get($command));
131
-			}
132
-		}
133
-	}
21
+    private IAppManager $appManager;
22
+
23
+    protected function setUp(): void {
24
+        parent::setUp();
25
+        $this->appManager = Server::get(IAppManager::class);
26
+    }
27
+
28
+    public static function dataApps(): array {
29
+        return [
30
+            ['admin_audit'],
31
+            ['comments'],
32
+            ['dav'],
33
+            ['encryption'],
34
+            ['federatedfilesharing'],
35
+            ['federation'],
36
+            ['files'],
37
+            ['files_external'],
38
+            ['files_sharing'],
39
+            ['files_trashbin'],
40
+            ['files_versions'],
41
+            ['provisioning_api'],
42
+            ['systemtags'],
43
+            ['theming'],
44
+            ['settings'],
45
+            ['twofactor_backupcodes'],
46
+            ['updatenotification'],
47
+            ['user_ldap'],
48
+            ['workflowengine'],
49
+        ];
50
+    }
51
+
52
+    /**
53
+     * @param string $app
54
+     */
55
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataApps')]
56
+    public function testClasses($app): void {
57
+        $appInfo = $this->appManager->getAppInfo($app);
58
+        $appPath = $this->appManager->getAppPath($app);
59
+        \OC_App::registerAutoloading($app, $appPath);
60
+
61
+        //Add the appcontainer
62
+        $applicationClassName = App::buildAppNamespace($app) . '\\AppInfo\\Application';
63
+        if (class_exists($applicationClassName)) {
64
+            $application = new $applicationClassName();
65
+            $this->addToAssertionCount(1);
66
+        } else {
67
+            $application = new App($app);
68
+            $this->addToAssertionCount(1);
69
+        }
70
+
71
+        if (isset($appInfo['background-jobs'])) {
72
+            foreach ($appInfo['background-jobs'] as $job) {
73
+                $this->assertTrue(class_exists($job), 'Asserting background job "' . $job . '" exists');
74
+                $this->assertInstanceOf($job, Server::get($job));
75
+            }
76
+        }
77
+
78
+        if (isset($appInfo['two-factor-providers'])) {
79
+            foreach ($appInfo['two-factor-providers'] as $provider) {
80
+                $this->assertTrue(class_exists($provider), 'Asserting two-factor providers "' . $provider . '" exists');
81
+                $this->assertInstanceOf($provider, Server::get($provider));
82
+            }
83
+        }
84
+
85
+        if (isset($appInfo['commands'])) {
86
+            foreach ($appInfo['commands'] as $command) {
87
+                $this->assertTrue(class_exists($command), 'Asserting command "' . $command . '" exists');
88
+                $this->assertInstanceOf($command, Server::get($command));
89
+            }
90
+        }
91
+
92
+        if (isset($appInfo['repair-steps']['pre-migration'])) {
93
+            foreach ($appInfo['repair-steps']['pre-migration'] as $migration) {
94
+                $this->assertTrue(class_exists($migration), 'Asserting pre-migration "' . $migration . '" exists');
95
+                $this->assertInstanceOf($migration, Server::get($migration));
96
+            }
97
+        }
98
+
99
+        if (isset($appInfo['repair-steps']['post-migration'])) {
100
+            foreach ($appInfo['repair-steps']['post-migration'] as $migration) {
101
+                $this->assertTrue(class_exists($migration), 'Asserting post-migration "' . $migration . '" exists');
102
+                $this->assertInstanceOf($migration, Server::get($migration));
103
+            }
104
+        }
105
+
106
+        if (isset($appInfo['repair-steps']['live-migration'])) {
107
+            foreach ($appInfo['repair-steps']['live-migration'] as $migration) {
108
+                $this->assertTrue(class_exists($migration), 'Asserting live-migration "' . $migration . '" exists');
109
+                $this->assertInstanceOf($migration, Server::get($migration));
110
+            }
111
+        }
112
+
113
+        if (isset($appInfo['repair-steps']['install'])) {
114
+            foreach ($appInfo['repair-steps']['install'] as $migration) {
115
+                $this->assertTrue(class_exists($migration), 'Asserting install-migration "' . $migration . '" exists');
116
+                $this->assertInstanceOf($migration, Server::get($migration));
117
+            }
118
+        }
119
+
120
+        if (isset($appInfo['repair-steps']['uninstall'])) {
121
+            foreach ($appInfo['repair-steps']['uninstall'] as $migration) {
122
+                $this->assertTrue(class_exists($migration), 'Asserting uninstall-migration "' . $migration . '" exists');
123
+                $this->assertInstanceOf($migration, Server::get($migration));
124
+            }
125
+        }
126
+
127
+        if (isset($appInfo['commands'])) {
128
+            foreach ($appInfo['commands'] as $command) {
129
+                $this->assertTrue(class_exists($command), 'Asserting command "' . $command . '"exists');
130
+                $this->assertInstanceOf($command, Server::get($command));
131
+            }
132
+        }
133
+    }
134 134
 }
Please login to merge, or discard this patch.
tests/lib/Share20/DefaultShareProviderTest.php 1 patch
Indentation   +3063 added lines, -3063 removed lines patch added patch discarded remove patch
@@ -44,3071 +44,3071 @@
 block discarded – undo
44 44
  */
45 45
 #[\PHPUnit\Framework\Attributes\Group('DB')]
46 46
 class DefaultShareProviderTest extends \Test\TestCase {
47
-	/** @var IDBConnection */
48
-	protected $dbConn;
49
-
50
-	/** @var IUserManager | MockObject */
51
-	protected $userManager;
52
-
53
-	/** @var IGroupManager | MockObject */
54
-	protected $groupManager;
55
-
56
-	/** @var IRootFolder | MockObject */
57
-	protected $rootFolder;
58
-
59
-	/** @var DefaultShareProvider */
60
-	protected $provider;
61
-
62
-	/** @var MockObject|IMailer */
63
-	protected $mailer;
64
-
65
-	/** @var IFactory|MockObject */
66
-	protected $l10nFactory;
67
-
68
-	/** @var MockObject|IL10N */
69
-	protected $l10n;
70
-
71
-	/** @var MockObject|Defaults */
72
-	protected $defaults;
73
-
74
-	/** @var MockObject|IURLGenerator */
75
-	protected $urlGenerator;
76
-
77
-	/** @var ITimeFactory|MockObject */
78
-	protected $timeFactory;
79
-
80
-	/** @var LoggerInterface|MockObject */
81
-	protected $logger;
82
-
83
-	protected IConfig&MockObject $config;
84
-
85
-	protected IShareManager&MockObject $shareManager;
86
-
87
-	protected function setUp(): void {
88
-		$this->dbConn = Server::get(IDBConnection::class);
89
-		$this->userManager = $this->createMock(IUserManager::class);
90
-		$this->groupManager = $this->createMock(IGroupManager::class);
91
-		$this->rootFolder = $this->createMock(IRootFolder::class);
92
-		$this->mailer = $this->createMock(IMailer::class);
93
-		$this->l10nFactory = $this->createMock(IFactory::class);
94
-		$this->l10n = $this->createMock(IL10N::class);
95
-		$this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock();
96
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
97
-		$this->timeFactory = $this->createMock(ITimeFactory::class);
98
-		$this->logger = $this->createMock(LoggerInterface::class);
99
-		$this->shareManager = $this->createMock(IShareManager::class);
100
-		$this->config = $this->createMock(IConfig::class);
101
-
102
-		$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
103
-		$this->timeFactory->expects($this->any())->method('now')->willReturn(new \DateTimeImmutable('2023-05-04 00:00 Europe/Berlin'));
104
-
105
-		//Empty share table
106
-		$this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
107
-
108
-		$this->provider = new DefaultShareProvider(
109
-			$this->dbConn,
110
-			$this->userManager,
111
-			$this->groupManager,
112
-			$this->rootFolder,
113
-			$this->mailer,
114
-			$this->defaults,
115
-			$this->l10nFactory,
116
-			$this->urlGenerator,
117
-			$this->timeFactory,
118
-			$this->logger,
119
-			$this->shareManager,
120
-			$this->config,
121
-		);
122
-	}
123
-
124
-	protected function tearDown(): void {
125
-		$this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
126
-		$this->dbConn->getQueryBuilder()->delete('filecache')->runAcrossAllShards()->executeStatement();
127
-		$this->dbConn->getQueryBuilder()->delete('storages')->executeStatement();
128
-	}
129
-
130
-	/**
131
-	 * @param int $shareType
132
-	 * @param string $sharedWith
133
-	 * @param string $sharedBy
134
-	 * @param string $shareOwner
135
-	 * @param string $itemType
136
-	 * @param int $fileSource
137
-	 * @param string $fileTarget
138
-	 * @param int $permissions
139
-	 * @param $token
140
-	 * @param $expiration
141
-	 * @return int
142
-	 */
143
-	private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner,
144
-		$itemType, $fileSource, $fileTarget, $permissions, $token, $expiration,
145
-		$parent = null) {
146
-		$qb = $this->dbConn->getQueryBuilder();
147
-		$qb->insert('share');
148
-
149
-		if ($shareType) {
150
-			$qb->setValue('share_type', $qb->expr()->literal($shareType));
151
-		}
152
-		if ($sharedWith) {
153
-			$qb->setValue('share_with', $qb->expr()->literal($sharedWith));
154
-		}
155
-		if ($sharedBy) {
156
-			$qb->setValue('uid_initiator', $qb->expr()->literal($sharedBy));
157
-		}
158
-		if ($shareOwner) {
159
-			$qb->setValue('uid_owner', $qb->expr()->literal($shareOwner));
160
-		}
161
-		if ($itemType) {
162
-			$qb->setValue('item_type', $qb->expr()->literal($itemType));
163
-		}
164
-		if ($fileSource) {
165
-			$qb->setValue('file_source', $qb->expr()->literal($fileSource));
166
-		}
167
-		if ($fileTarget) {
168
-			$qb->setValue('file_target', $qb->expr()->literal($fileTarget));
169
-		}
170
-		if ($permissions) {
171
-			$qb->setValue('permissions', $qb->expr()->literal($permissions));
172
-		}
173
-		if ($token) {
174
-			$qb->setValue('token', $qb->expr()->literal($token));
175
-		}
176
-		if ($expiration) {
177
-			$qb->setValue('expiration', $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_DATETIME_MUTABLE));
178
-		}
179
-		if ($parent) {
180
-			$qb->setValue('parent', $qb->expr()->literal($parent));
181
-		}
182
-
183
-		$this->assertEquals(1, $qb->executeStatement());
184
-		return $qb->getLastInsertId();
185
-	}
186
-
187
-
188
-
189
-
190
-	public function testGetShareByIdNotExist(): void {
191
-		$this->expectException(ShareNotFound::class);
192
-
193
-		$this->provider->getShareById(1);
194
-	}
195
-
196
-	public function testGetShareByIdUserShare(): void {
197
-		$qb = $this->dbConn->getQueryBuilder();
198
-
199
-		$qb->insert('share')
200
-			->values([
201
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
202
-				'share_with' => $qb->expr()->literal('sharedWith'),
203
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
204
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
205
-				'item_type' => $qb->expr()->literal('file'),
206
-				'file_source' => $qb->expr()->literal(42),
207
-				'file_target' => $qb->expr()->literal('myTarget'),
208
-				'permissions' => $qb->expr()->literal(13),
209
-			]);
210
-		$qb->executeStatement();
211
-
212
-		$id = $qb->getLastInsertId();
213
-
214
-		$sharedBy = $this->createMock(IUser::class);
215
-		$sharedBy->method('getUID')->willReturn('sharedBy');
216
-		$shareOwner = $this->createMock(IUser::class);
217
-		$shareOwner->method('getUID')->willReturn('shareOwner');
218
-
219
-		$ownerPath = $this->createMock(File::class);
220
-		$shareOwnerFolder = $this->createMock(Folder::class);
221
-		$shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
222
-
223
-		$this->rootFolder
224
-			->method('getUserFolder')
225
-			->willReturnMap([
226
-				['shareOwner', $shareOwnerFolder],
227
-			]);
228
-
229
-		$share = $this->provider->getShareById($id);
230
-
231
-		$this->assertEquals($id, $share->getId());
232
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
233
-		$this->assertEquals('sharedWith', $share->getSharedWith());
234
-		$this->assertEquals('sharedBy', $share->getSharedBy());
235
-		$this->assertEquals('shareOwner', $share->getShareOwner());
236
-		$this->assertEquals($ownerPath, $share->getNode());
237
-		$this->assertEquals(13, $share->getPermissions());
238
-		$this->assertEquals(null, $share->getToken());
239
-		$this->assertEquals(null, $share->getExpirationDate());
240
-		$this->assertEquals('myTarget', $share->getTarget());
241
-	}
242
-
243
-	public function testGetShareByIdLazy(): void {
244
-		$qb = $this->dbConn->getQueryBuilder();
245
-
246
-		$qb->insert('share')
247
-			->values([
248
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
249
-				'share_with' => $qb->expr()->literal('sharedWith'),
250
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
251
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
252
-				'item_type' => $qb->expr()->literal('file'),
253
-				'file_source' => $qb->expr()->literal(42),
254
-				'file_target' => $qb->expr()->literal('myTarget'),
255
-				'permissions' => $qb->expr()->literal(13),
256
-			]);
257
-		$qb->executeStatement();
258
-
259
-		$id = $qb->getLastInsertId();
260
-
261
-		$this->rootFolder->expects($this->never())->method('getUserFolder');
262
-
263
-		$share = $this->provider->getShareById($id);
264
-
265
-		// We do not fetch the node so the rootfolder is never called.
266
-
267
-		$this->assertEquals($id, $share->getId());
268
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
269
-		$this->assertEquals('sharedWith', $share->getSharedWith());
270
-		$this->assertEquals('sharedBy', $share->getSharedBy());
271
-		$this->assertEquals('shareOwner', $share->getShareOwner());
272
-		$this->assertEquals(13, $share->getPermissions());
273
-		$this->assertEquals(null, $share->getToken());
274
-		$this->assertEquals(null, $share->getExpirationDate());
275
-		$this->assertEquals('myTarget', $share->getTarget());
276
-	}
277
-
278
-	public function testGetShareByIdLazy2(): void {
279
-		$qb = $this->dbConn->getQueryBuilder();
280
-
281
-		$qb->insert('share')
282
-			->values([
283
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
284
-				'share_with' => $qb->expr()->literal('sharedWith'),
285
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
286
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
287
-				'item_type' => $qb->expr()->literal('file'),
288
-				'file_source' => $qb->expr()->literal(42),
289
-				'file_target' => $qb->expr()->literal('myTarget'),
290
-				'permissions' => $qb->expr()->literal(13),
291
-			]);
292
-		$qb->executeStatement();
293
-
294
-		$id = $qb->getLastInsertId();
295
-
296
-		$ownerPath = $this->createMock(File::class);
297
-
298
-		$shareOwnerFolder = $this->createMock(Folder::class);
299
-		$shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
300
-
301
-		$this->rootFolder
302
-			->method('getUserFolder')
303
-			->with('shareOwner')
304
-			->willReturn($shareOwnerFolder);
305
-
306
-		$share = $this->provider->getShareById($id);
307
-
308
-		// We fetch the node so the root folder is eventually called
309
-
310
-		$this->assertEquals($id, $share->getId());
311
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
312
-		$this->assertEquals('sharedWith', $share->getSharedWith());
313
-		$this->assertEquals('sharedBy', $share->getSharedBy());
314
-		$this->assertEquals('shareOwner', $share->getShareOwner());
315
-		$this->assertEquals($ownerPath, $share->getNode());
316
-		$this->assertEquals(13, $share->getPermissions());
317
-		$this->assertEquals(null, $share->getToken());
318
-		$this->assertEquals(null, $share->getExpirationDate());
319
-		$this->assertEquals('myTarget', $share->getTarget());
320
-	}
321
-
322
-	public function testGetShareByIdGroupShare(): void {
323
-		$qb = $this->dbConn->getQueryBuilder();
324
-
325
-		$qb->insert('share')
326
-			->values([
327
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
328
-				'share_with' => $qb->expr()->literal('sharedWith'),
329
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
330
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
331
-				'item_type' => $qb->expr()->literal('file'),
332
-				'file_source' => $qb->expr()->literal(42),
333
-				'file_target' => $qb->expr()->literal('myTarget'),
334
-				'permissions' => $qb->expr()->literal(13),
335
-			]);
336
-		$this->assertEquals(1, $qb->executeStatement());
337
-
338
-		// Get the id
339
-		$id = $qb->getLastInsertId();
340
-
341
-		$ownerPath = $this->createMock(Folder::class);
342
-		$shareOwnerFolder = $this->createMock(Folder::class);
343
-		$shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
344
-
345
-		$this->rootFolder
346
-			->method('getUserFolder')
347
-			->willReturnMap([
348
-				['shareOwner', $shareOwnerFolder],
349
-			]);
350
-
351
-		$share = $this->provider->getShareById($id);
352
-
353
-		$this->assertEquals($id, $share->getId());
354
-		$this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
355
-		$this->assertEquals('sharedWith', $share->getSharedWith());
356
-		$this->assertEquals('sharedBy', $share->getSharedBy());
357
-		$this->assertEquals('shareOwner', $share->getShareOwner());
358
-		$this->assertEquals($ownerPath, $share->getNode());
359
-		$this->assertEquals(13, $share->getPermissions());
360
-		$this->assertEquals(null, $share->getToken());
361
-		$this->assertEquals(null, $share->getExpirationDate());
362
-		$this->assertEquals('myTarget', $share->getTarget());
363
-	}
364
-
365
-	public function testGetShareByIdUserGroupShare(): void {
366
-		$id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user0', 'user0', 'file', 42, 'myTarget', 31, null, null);
367
-		$this->addShareToDB(2, 'user1', 'user0', 'user0', 'file', 42, 'userTarget', 0, null, null, $id);
368
-
369
-		$user0 = $this->createMock(IUser::class);
370
-		$user0->method('getUID')->willReturn('user0');
371
-		$user1 = $this->createMock(IUser::class);
372
-		$user1->method('getUID')->willReturn('user1');
373
-
374
-		$group0 = $this->createMock(IGroup::class);
375
-		$group0->method('inGroup')->with($user1)->willReturn(true);
376
-		$group0->method('getDisplayName')->willReturn('g0-displayname');
377
-
378
-		$node = $this->createMock(Folder::class);
379
-		$node->method('getId')->willReturn(42);
380
-		$node->method('getName')->willReturn('myTarget');
381
-
382
-		$this->rootFolder->method('getUserFolder')->with('user0')->willReturnSelf();
383
-		$this->rootFolder->method('getFirstNodeById')->willReturn($node);
384
-
385
-		$this->userManager->method('get')->willReturnMap([
386
-			['user0', $user0],
387
-			['user1', $user1],
388
-		]);
389
-		$this->groupManager->method('get')->with('group0')->willReturn($group0);
390
-
391
-		$share = $this->provider->getShareById($id, 'user1');
392
-
393
-		$this->assertEquals($id, $share->getId());
394
-		$this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
395
-		$this->assertSame('group0', $share->getSharedWith());
396
-		$this->assertSame('user0', $share->getSharedBy());
397
-		$this->assertSame('user0', $share->getShareOwner());
398
-		$this->assertSame($node, $share->getNode());
399
-		$this->assertEquals(0, $share->getPermissions());
400
-		$this->assertEquals(null, $share->getToken());
401
-		$this->assertEquals(null, $share->getExpirationDate());
402
-		$this->assertEquals('userTarget', $share->getTarget());
403
-	}
404
-
405
-	public function testGetShareByIdLinkShare(): void {
406
-		$qb = $this->dbConn->getQueryBuilder();
407
-
408
-		$qb->insert('share')
409
-			->values([
410
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
411
-				'password' => $qb->expr()->literal('password'),
412
-				'password_by_talk' => $qb->expr()->literal(true),
413
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
414
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
415
-				'item_type' => $qb->expr()->literal('file'),
416
-				'file_source' => $qb->expr()->literal(42),
417
-				'file_target' => $qb->expr()->literal('myTarget'),
418
-				'permissions' => $qb->expr()->literal(13),
419
-				'token' => $qb->expr()->literal('token'),
420
-				'expiration' => $qb->expr()->literal('2000-01-02 00:00:00'),
421
-			]);
422
-		$this->assertEquals(1, $qb->executeStatement());
423
-
424
-		$id = $qb->getLastInsertId();
425
-
426
-		$ownerPath = $this->createMock(Folder::class);
427
-		$shareOwnerFolder = $this->createMock(Folder::class);
428
-		$shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
429
-
430
-		$this->rootFolder
431
-			->method('getUserFolder')
432
-			->willReturnMap([
433
-				['shareOwner', $shareOwnerFolder],
434
-			]);
435
-
436
-		$share = $this->provider->getShareById($id);
437
-
438
-		$this->assertEquals($id, $share->getId());
439
-		$this->assertEquals(IShare::TYPE_LINK, $share->getShareType());
440
-		$this->assertNull($share->getSharedWith());
441
-		$this->assertEquals('password', $share->getPassword());
442
-		$this->assertEquals(true, $share->getSendPasswordByTalk());
443
-		$this->assertEquals('sharedBy', $share->getSharedBy());
444
-		$this->assertEquals('shareOwner', $share->getShareOwner());
445
-		$this->assertEquals($ownerPath, $share->getNode());
446
-		$this->assertEquals(13, $share->getPermissions());
447
-		$this->assertEquals('token', $share->getToken());
448
-		$this->assertEquals(\DateTime::createFromFormat('Y-m-d H:i:s', '2000-01-02 00:00:00'), $share->getExpirationDate());
449
-		$this->assertEquals('myTarget', $share->getTarget());
450
-	}
451
-
452
-	public function testDeleteSingleShare(): void {
453
-		$qb = $this->dbConn->getQueryBuilder();
454
-		$qb->insert('share')
455
-			->values([
456
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
457
-				'share_with' => $qb->expr()->literal('sharedWith'),
458
-				'uid_owner' => $qb->expr()->literal('sharedBy'),
459
-				'item_type' => $qb->expr()->literal('file'),
460
-				'file_source' => $qb->expr()->literal(42),
461
-				'file_target' => $qb->expr()->literal('myTarget'),
462
-				'permissions' => $qb->expr()->literal(13),
463
-			]);
464
-		$this->assertEquals(1, $qb->executeStatement());
465
-
466
-		$id = $qb->getLastInsertId();
467
-
468
-		$share = $this->createMock(IShare::class);
469
-		$share->method('getId')->willReturn($id);
470
-
471
-		/** @var DefaultShareProvider $provider */
472
-		$provider = $this->getMockBuilder(DefaultShareProvider::class)
473
-			->setConstructorArgs([
474
-				$this->dbConn,
475
-				$this->userManager,
476
-				$this->groupManager,
477
-				$this->rootFolder,
478
-				$this->mailer,
479
-				$this->defaults,
480
-				$this->l10nFactory,
481
-				$this->urlGenerator,
482
-				$this->timeFactory,
483
-				$this->logger,
484
-				$this->shareManager,
485
-				$this->config,
486
-			])
487
-			->onlyMethods(['getShareById'])
488
-			->getMock();
489
-
490
-		$provider->delete($share);
491
-
492
-		$qb = $this->dbConn->getQueryBuilder();
493
-		$qb->select('*')
494
-			->from('share');
495
-
496
-		$cursor = $qb->executeQuery();
497
-		$result = $cursor->fetchAll();
498
-		$cursor->closeCursor();
499
-
500
-		$this->assertEmpty($result);
501
-	}
502
-
503
-	public function testDeleteSingleShareLazy(): void {
504
-		$qb = $this->dbConn->getQueryBuilder();
505
-		$qb->insert('share')
506
-			->values([
507
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
508
-				'share_with' => $qb->expr()->literal('sharedWith'),
509
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
510
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
511
-				'item_type' => $qb->expr()->literal('file'),
512
-				'file_source' => $qb->expr()->literal(42),
513
-				'file_target' => $qb->expr()->literal('myTarget'),
514
-				'permissions' => $qb->expr()->literal(13),
515
-			]);
516
-		$this->assertEquals(1, $qb->executeStatement());
517
-
518
-		$id = $qb->getLastInsertId();
519
-
520
-		$this->rootFolder->expects($this->never())->method($this->anything());
521
-
522
-		$share = $this->provider->getShareById($id);
523
-		$this->provider->delete($share);
524
-
525
-		$qb = $this->dbConn->getQueryBuilder();
526
-		$qb->select('*')
527
-			->from('share');
528
-
529
-		$cursor = $qb->executeQuery();
530
-		$result = $cursor->fetchAll();
531
-		$cursor->closeCursor();
532
-
533
-		$this->assertEmpty($result);
534
-	}
535
-
536
-	public function testDeleteGroupShareWithUserGroupShares(): void {
537
-		$qb = $this->dbConn->getQueryBuilder();
538
-		$qb->insert('share')
539
-			->values([
540
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
541
-				'share_with' => $qb->expr()->literal('sharedWith'),
542
-				'uid_owner' => $qb->expr()->literal('sharedBy'),
543
-				'item_type' => $qb->expr()->literal('file'),
544
-				'file_source' => $qb->expr()->literal(42),
545
-				'file_target' => $qb->expr()->literal('myTarget'),
546
-				'permissions' => $qb->expr()->literal(13),
547
-			]);
548
-		$this->assertEquals(1, $qb->executeStatement());
549
-		$id = $qb->getLastInsertId();
550
-
551
-		$qb = $this->dbConn->getQueryBuilder();
552
-		$qb->insert('share')
553
-			->values([
554
-				'share_type' => $qb->expr()->literal(2),
555
-				'share_with' => $qb->expr()->literal('sharedWithUser'),
556
-				'uid_owner' => $qb->expr()->literal('sharedBy'),
557
-				'item_type' => $qb->expr()->literal('file'),
558
-				'file_source' => $qb->expr()->literal(42),
559
-				'file_target' => $qb->expr()->literal('myTarget'),
560
-				'permissions' => $qb->expr()->literal(13),
561
-				'parent' => $qb->expr()->literal($id),
562
-			]);
563
-		$this->assertEquals(1, $qb->executeStatement());
564
-
565
-		$share = $this->createMock(IShare::class);
566
-		$share->method('getId')->willReturn($id);
567
-		$share->method('getShareType')->willReturn(IShare::TYPE_GROUP);
568
-
569
-		/** @var DefaultShareProvider $provider */
570
-		$provider = $this->getMockBuilder(DefaultShareProvider::class)
571
-			->setConstructorArgs([
572
-				$this->dbConn,
573
-				$this->userManager,
574
-				$this->groupManager,
575
-				$this->rootFolder,
576
-				$this->mailer,
577
-				$this->defaults,
578
-				$this->l10nFactory,
579
-				$this->urlGenerator,
580
-				$this->timeFactory,
581
-				$this->logger,
582
-				$this->shareManager,
583
-				$this->config,
584
-			])
585
-			->onlyMethods(['getShareById'])
586
-			->getMock();
587
-
588
-		$provider->delete($share);
589
-
590
-		$qb = $this->dbConn->getQueryBuilder();
591
-		$qb->select('*')
592
-			->from('share');
593
-
594
-		$cursor = $qb->executeQuery();
595
-		$result = $cursor->fetchAll();
596
-		$cursor->closeCursor();
597
-
598
-		$this->assertEmpty($result);
599
-	}
600
-
601
-	public function testGetChildren(): void {
602
-		$qb = $this->dbConn->getQueryBuilder();
603
-		$qb->insert('share')
604
-			->values([
605
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
606
-				'share_with' => $qb->expr()->literal('sharedWith'),
607
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
608
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
609
-				'item_type' => $qb->expr()->literal('file'),
610
-				'file_source' => $qb->expr()->literal(42),
611
-				'file_target' => $qb->expr()->literal('myTarget'),
612
-				'permissions' => $qb->expr()->literal(13),
613
-			]);
614
-		$qb->executeStatement();
615
-
616
-		// Get the id
617
-		$id = $qb->getLastInsertId();
618
-
619
-		$qb = $this->dbConn->getQueryBuilder();
620
-		$qb->insert('share')
621
-			->values([
622
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
623
-				'share_with' => $qb->expr()->literal('user1'),
624
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
625
-				'uid_initiator' => $qb->expr()->literal('user2'),
626
-				'item_type' => $qb->expr()->literal('file'),
627
-				'file_source' => $qb->expr()->literal(1),
628
-				'file_target' => $qb->expr()->literal('myTarget1'),
629
-				'permissions' => $qb->expr()->literal(2),
630
-				'parent' => $qb->expr()->literal($id),
631
-			]);
632
-		$qb->executeStatement();
633
-
634
-		$qb = $this->dbConn->getQueryBuilder();
635
-		$qb->insert('share')
636
-			->values([
637
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
638
-				'share_with' => $qb->expr()->literal('group1'),
639
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
640
-				'uid_initiator' => $qb->expr()->literal('user3'),
641
-				'item_type' => $qb->expr()->literal('folder'),
642
-				'file_source' => $qb->expr()->literal(3),
643
-				'file_target' => $qb->expr()->literal('myTarget2'),
644
-				'permissions' => $qb->expr()->literal(4),
645
-				'parent' => $qb->expr()->literal($id),
646
-			]);
647
-		$qb->executeStatement();
648
-
649
-		$ownerPath = $this->createMock(Folder::class);
650
-		$ownerFolder = $this->createMock(Folder::class);
651
-		$ownerFolder->method('getFirstNodeById')->willReturn($ownerPath);
652
-
653
-		$this->rootFolder
654
-			->method('getUserFolder')
655
-			->willReturnMap([
656
-				['shareOwner', $ownerFolder],
657
-			]);
658
-
659
-		$share = $this->createMock(IShare::class);
660
-		$share->method('getId')->willReturn($id);
661
-
662
-		$children = $this->provider->getChildren($share);
663
-
664
-		$this->assertCount(2, $children);
665
-
666
-		//Child1
667
-		$this->assertEquals(IShare::TYPE_USER, $children[0]->getShareType());
668
-		$this->assertEquals('user1', $children[0]->getSharedWith());
669
-		$this->assertEquals('user2', $children[0]->getSharedBy());
670
-		$this->assertEquals('shareOwner', $children[0]->getShareOwner());
671
-		$this->assertEquals($ownerPath, $children[0]->getNode());
672
-		$this->assertEquals(2, $children[0]->getPermissions());
673
-		$this->assertEquals(null, $children[0]->getToken());
674
-		$this->assertEquals(null, $children[0]->getExpirationDate());
675
-		$this->assertEquals('myTarget1', $children[0]->getTarget());
676
-
677
-		//Child2
678
-		$this->assertEquals(IShare::TYPE_GROUP, $children[1]->getShareType());
679
-		$this->assertEquals('group1', $children[1]->getSharedWith());
680
-		$this->assertEquals('user3', $children[1]->getSharedBy());
681
-		$this->assertEquals('shareOwner', $children[1]->getShareOwner());
682
-		$this->assertEquals($ownerPath, $children[1]->getNode());
683
-		$this->assertEquals(4, $children[1]->getPermissions());
684
-		$this->assertEquals(null, $children[1]->getToken());
685
-		$this->assertEquals(null, $children[1]->getExpirationDate());
686
-		$this->assertEquals('myTarget2', $children[1]->getTarget());
687
-	}
688
-
689
-	public function testCreateUserShare(): void {
690
-		$share = new Share($this->rootFolder, $this->userManager);
691
-
692
-		$shareOwner = $this->createMock(IUser::class);
693
-		$shareOwner->method('getUID')->willReturn('shareOwner');
694
-
695
-		$path = $this->createMock(File::class);
696
-		$path->method('getId')->willReturn(100);
697
-		$path->method('getOwner')->willReturn($shareOwner);
698
-
699
-		$ownerFolder = $this->createMock(Folder::class);
700
-		$userFolder = $this->createMock(Folder::class);
701
-		$this->rootFolder
702
-			->method('getUserFolder')
703
-			->willReturnMap([
704
-				['sharedBy', $userFolder],
705
-				['shareOwner', $ownerFolder],
706
-			]);
707
-
708
-		$userFolder->method('getFirstNodeById')
709
-			->with(100)
710
-			->willReturn($path);
711
-		$ownerFolder->method('getFirstNodeById')
712
-			->with(100)
713
-			->willReturn($path);
714
-
715
-		$share->setShareType(IShare::TYPE_USER);
716
-		$share->setSharedWith('sharedWith');
717
-		$share->setSharedBy('sharedBy');
718
-		$share->setShareOwner('shareOwner');
719
-		$share->setNode($path);
720
-		$share->setSharedWithDisplayName('Displayed Name');
721
-		$share->setSharedWithAvatar('/path/to/image.svg');
722
-		$share->setPermissions(1);
723
-
724
-		$attrs = new ShareAttributes();
725
-		$attrs->setAttribute('permissions', 'download', true);
726
-		$share->setAttributes($attrs);
727
-
728
-		$share->setTarget('/target');
729
-
730
-		$share2 = $this->provider->create($share);
731
-
732
-		$this->assertNotNull($share2->getId());
733
-		$this->assertSame('ocinternal:' . $share2->getId(), $share2->getFullId());
734
-		$this->assertSame(IShare::TYPE_USER, $share2->getShareType());
735
-		$this->assertSame('sharedWith', $share2->getSharedWith());
736
-		$this->assertSame('sharedBy', $share2->getSharedBy());
737
-		$this->assertSame('shareOwner', $share2->getShareOwner());
738
-		$this->assertSame(1, $share2->getPermissions());
739
-		$this->assertSame('/target', $share2->getTarget());
740
-		$this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime());
741
-		$this->assertSame($path, $share2->getNode());
742
-
743
-		// Data is kept after creation
744
-		$this->assertSame('Displayed Name', $share->getSharedWithDisplayName());
745
-		$this->assertSame('/path/to/image.svg', $share->getSharedWithAvatar());
746
-		$this->assertSame('Displayed Name', $share2->getSharedWithDisplayName());
747
-		$this->assertSame('/path/to/image.svg', $share2->getSharedWithAvatar());
748
-
749
-		$this->assertSame(
750
-			[
751
-				[
752
-					'scope' => 'permissions',
753
-					'key' => 'download',
754
-					'value' => true
755
-				]
756
-			],
757
-			$share->getAttributes()->toArray()
758
-		);
759
-	}
760
-
761
-	public function testCreateGroupShare(): void {
762
-		$share = new Share($this->rootFolder, $this->userManager);
763
-
764
-		$shareOwner = $this->createMock(IUser::class);
765
-		$shareOwner->method('getUID')->willReturn('shareOwner');
766
-
767
-		$path = $this->createMock(Folder::class);
768
-		$path->method('getId')->willReturn(100);
769
-		$path->method('getOwner')->willReturn($shareOwner);
770
-
771
-		$ownerFolder = $this->createMock(Folder::class);
772
-		$userFolder = $this->createMock(Folder::class);
773
-		$this->rootFolder
774
-			->method('getUserFolder')
775
-			->willReturnMap([
776
-				['sharedBy', $userFolder],
777
-				['shareOwner', $ownerFolder],
778
-			]);
779
-
780
-		$userFolder->method('getFirstNodeById')
781
-			->with(100)
782
-			->willReturn($path);
783
-		$ownerFolder->method('getFirstNodeById')
784
-			->with(100)
785
-			->willReturn($path);
786
-
787
-		$share->setShareType(IShare::TYPE_GROUP);
788
-		$share->setSharedWith('sharedWith');
789
-		$share->setSharedBy('sharedBy');
790
-		$share->setShareOwner('shareOwner');
791
-		$share->setNode($path);
792
-		$share->setPermissions(1);
793
-		$share->setSharedWithDisplayName('Displayed Name');
794
-		$share->setSharedWithAvatar('/path/to/image.svg');
795
-		$share->setTarget('/target');
796
-		$attrs = new ShareAttributes();
797
-		$attrs->setAttribute('permissions', 'download', true);
798
-		$share->setAttributes($attrs);
799
-
800
-		$share2 = $this->provider->create($share);
801
-
802
-		$this->assertNotNull($share2->getId());
803
-		$this->assertSame('ocinternal:' . $share2->getId(), $share2->getFullId());
804
-		$this->assertSame(IShare::TYPE_GROUP, $share2->getShareType());
805
-		$this->assertSame('sharedWith', $share2->getSharedWith());
806
-		$this->assertSame('sharedBy', $share2->getSharedBy());
807
-		$this->assertSame('shareOwner', $share2->getShareOwner());
808
-		$this->assertSame(1, $share2->getPermissions());
809
-		$this->assertSame('/target', $share2->getTarget());
810
-		$this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime());
811
-		$this->assertSame($path, $share2->getNode());
812
-
813
-		// Data is kept after creation
814
-		$this->assertSame('Displayed Name', $share->getSharedWithDisplayName());
815
-		$this->assertSame('/path/to/image.svg', $share->getSharedWithAvatar());
816
-		$this->assertSame('Displayed Name', $share2->getSharedWithDisplayName());
817
-		$this->assertSame('/path/to/image.svg', $share2->getSharedWithAvatar());
818
-
819
-		$this->assertSame(
820
-			[
821
-				[
822
-					'scope' => 'permissions',
823
-					'key' => 'download',
824
-					'value' => true
825
-				]
826
-			],
827
-			$share->getAttributes()->toArray()
828
-		);
829
-	}
830
-
831
-	public function testCreateLinkShare(): void {
832
-		$share = new Share($this->rootFolder, $this->userManager);
833
-
834
-		$shareOwner = $this->createMock(IUser::class);
835
-		$shareOwner->method('getUID')->willReturn('shareOwner');
836
-
837
-		$path = $this->createMock(Folder::class);
838
-		$path->method('getId')->willReturn(100);
839
-		$path->method('getOwner')->willReturn($shareOwner);
840
-
841
-		$ownerFolder = $this->createMock(Folder::class);
842
-		$userFolder = $this->createMock(Folder::class);
843
-		$this->rootFolder
844
-			->method('getUserFolder')
845
-			->willReturnMap([
846
-				['sharedBy', $userFolder],
847
-				['shareOwner', $ownerFolder],
848
-			]);
849
-
850
-		$userFolder->method('getFirstNodeById')
851
-			->with(100)
852
-			->willReturn($path);
853
-		$ownerFolder->method('getFirstNodeById')
854
-			->with(100)
855
-			->willReturn($path);
856
-
857
-		$share->setShareType(IShare::TYPE_LINK);
858
-		$share->setSharedBy('sharedBy');
859
-		$share->setShareOwner('shareOwner');
860
-		$share->setNode($path);
861
-		$share->setPermissions(1);
862
-		$share->setPassword('password');
863
-		$share->setSendPasswordByTalk(true);
864
-		$share->setToken('token');
865
-		$expireDate = new \DateTime();
866
-		$share->setExpirationDate($expireDate);
867
-		$share->setTarget('/target');
868
-
869
-		$share2 = $this->provider->create($share);
870
-
871
-		$this->assertNotNull($share2->getId());
872
-		$this->assertSame('ocinternal:' . $share2->getId(), $share2->getFullId());
873
-		$this->assertSame(IShare::TYPE_LINK, $share2->getShareType());
874
-		$this->assertSame('sharedBy', $share2->getSharedBy());
875
-		$this->assertSame('shareOwner', $share2->getShareOwner());
876
-		$this->assertSame(1, $share2->getPermissions());
877
-		$this->assertSame('/target', $share2->getTarget());
878
-		$this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime());
879
-		$this->assertSame($path, $share2->getNode());
880
-		$this->assertSame('password', $share2->getPassword());
881
-		$this->assertSame(true, $share2->getSendPasswordByTalk());
882
-		$this->assertSame('token', $share2->getToken());
883
-		$this->assertEquals($expireDate->getTimestamp(), $share2->getExpirationDate()->getTimestamp());
884
-	}
885
-
886
-	public function testGetShareByToken(): void {
887
-		$qb = $this->dbConn->getQueryBuilder();
888
-
889
-		$qb->insert('share')
890
-			->values([
891
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
892
-				'password' => $qb->expr()->literal('password'),
893
-				'password_by_talk' => $qb->expr()->literal(true),
894
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
895
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
896
-				'item_type' => $qb->expr()->literal('file'),
897
-				'file_source' => $qb->expr()->literal(42),
898
-				'file_target' => $qb->expr()->literal('myTarget'),
899
-				'permissions' => $qb->expr()->literal(13),
900
-				'token' => $qb->expr()->literal('secrettoken'),
901
-				'label' => $qb->expr()->literal('the label'),
902
-			]);
903
-		$qb->executeStatement();
904
-		$id = $qb->getLastInsertId();
905
-
906
-		$file = $this->createMock(File::class);
907
-
908
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
909
-		$this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
910
-
911
-		$share = $this->provider->getShareByToken('secrettoken');
912
-		$this->assertEquals($id, $share->getId());
913
-		$this->assertSame('shareOwner', $share->getShareOwner());
914
-		$this->assertSame('sharedBy', $share->getSharedBy());
915
-		$this->assertSame('secrettoken', $share->getToken());
916
-		$this->assertSame('password', $share->getPassword());
917
-		$this->assertSame('the label', $share->getLabel());
918
-		$this->assertSame(true, $share->getSendPasswordByTalk());
919
-		$this->assertSame(null, $share->getSharedWith());
920
-	}
921
-
922
-	/**
923
-	 * Assert that if no label is provided the label is correctly,
924
-	 * as types on IShare, a string and not null
925
-	 */
926
-	public function testGetShareByTokenNullLabel(): void {
927
-		$qb = $this->dbConn->getQueryBuilder();
928
-
929
-		$qb->insert('share')
930
-			->values([
931
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
932
-				'password' => $qb->expr()->literal('password'),
933
-				'password_by_talk' => $qb->expr()->literal(true),
934
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
935
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
936
-				'item_type' => $qb->expr()->literal('file'),
937
-				'file_source' => $qb->expr()->literal(42),
938
-				'file_target' => $qb->expr()->literal('myTarget'),
939
-				'permissions' => $qb->expr()->literal(13),
940
-				'token' => $qb->expr()->literal('secrettoken'),
941
-			]);
942
-		$qb->executeStatement();
943
-		$id = $qb->getLastInsertId();
944
-
945
-		$file = $this->createMock(File::class);
946
-
947
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
948
-		$this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
949
-
950
-		$share = $this->provider->getShareByToken('secrettoken');
951
-		$this->assertEquals($id, $share->getId());
952
-		$this->assertSame('', $share->getLabel());
953
-	}
954
-
955
-	public function testGetShareByTokenNotFound(): void {
956
-		$this->expectException(ShareNotFound::class);
957
-
958
-		$this->provider->getShareByToken('invalidtoken');
959
-	}
960
-
961
-	private function createTestStorageEntry($storageStringId) {
962
-		$qb = $this->dbConn->getQueryBuilder();
963
-		$qb->insert('storages')
964
-			->values([
965
-				'id' => $qb->expr()->literal($storageStringId),
966
-			]);
967
-		$this->assertEquals(1, $qb->executeStatement());
968
-		return $qb->getLastInsertId();
969
-	}
970
-
971
-	private function createTestFileEntry($path, $storage = 1) {
972
-		$qb = $this->dbConn->getQueryBuilder();
973
-		$qb->insert('filecache')
974
-			->values([
975
-				'storage' => $qb->createNamedParameter($storage, IQueryBuilder::PARAM_INT),
976
-				'path' => $qb->createNamedParameter($path),
977
-				'path_hash' => $qb->createNamedParameter(md5($path)),
978
-				'name' => $qb->createNamedParameter(basename($path)),
979
-			]);
980
-		$this->assertEquals(1, $qb->executeStatement());
981
-		return $qb->getLastInsertId();
982
-	}
983
-
984
-	public static function storageAndFileNameProvider(): array {
985
-		return [
986
-			// regular file on regular storage
987
-			['home::shareOwner', 'files/test.txt', 'files/test2.txt'],
988
-			// regular file on external storage
989
-			['smb::whatever', 'files/test.txt', 'files/test2.txt'],
990
-			// regular file on external storage in trashbin-like folder,
991
-			['smb::whatever', 'files_trashbin/files/test.txt', 'files_trashbin/files/test2.txt'],
992
-		];
993
-	}
994
-
995
-	#[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
996
-	public function testGetSharedWithUser($storageStringId, $fileName1, $fileName2): void {
997
-		$storageId = $this->createTestStorageEntry($storageStringId);
998
-		$fileId = $this->createTestFileEntry($fileName1, $storageId);
999
-		$fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1000
-		$qb = $this->dbConn->getQueryBuilder();
1001
-		$qb->insert('share')
1002
-			->values([
1003
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1004
-				'share_with' => $qb->expr()->literal('sharedWith'),
1005
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1006
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1007
-				'item_type' => $qb->expr()->literal('file'),
1008
-				'file_source' => $qb->expr()->literal($fileId),
1009
-				'file_target' => $qb->expr()->literal('myTarget'),
1010
-				'permissions' => $qb->expr()->literal(13),
1011
-			]);
1012
-		$this->assertEquals(1, $qb->executeStatement());
1013
-		$id = $qb->getLastInsertId();
1014
-
1015
-		$qb = $this->dbConn->getQueryBuilder();
1016
-		$qb->insert('share')
1017
-			->values([
1018
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1019
-				'share_with' => $qb->expr()->literal('sharedWith2'),
1020
-				'uid_owner' => $qb->expr()->literal('shareOwner2'),
1021
-				'uid_initiator' => $qb->expr()->literal('sharedBy2'),
1022
-				'item_type' => $qb->expr()->literal('file2'),
1023
-				'file_source' => $qb->expr()->literal($fileId2),
1024
-				'file_target' => $qb->expr()->literal('myTarget2'),
1025
-				'permissions' => $qb->expr()->literal(14),
1026
-			]);
1027
-		$this->assertEquals(1, $qb->executeStatement());
1028
-
1029
-		$file = $this->createMock(File::class);
1030
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1031
-		$this->rootFolder->method('getFirstNodeById')->with($fileId)->willReturn($file);
1032
-
1033
-		$share = $this->provider->getSharedWith('sharedWith', IShare::TYPE_USER, null, 1, 0);
1034
-		$this->assertCount(1, $share);
1035
-
1036
-		$share = $share[0];
1037
-		$this->assertEquals($id, $share->getId());
1038
-		$this->assertEquals('sharedWith', $share->getSharedWith());
1039
-		$this->assertEquals('shareOwner', $share->getShareOwner());
1040
-		$this->assertEquals('sharedBy', $share->getSharedBy());
1041
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1042
-	}
1043
-
1044
-	#[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1045
-	public function testGetSharedWithGroup($storageStringId, $fileName1, $fileName2): void {
1046
-		$storageId = $this->createTestStorageEntry($storageStringId);
1047
-		$fileId = $this->createTestFileEntry($fileName1, $storageId);
1048
-		$fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1049
-		$qb = $this->dbConn->getQueryBuilder();
1050
-		$qb->insert('share')
1051
-			->values([
1052
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1053
-				'share_with' => $qb->expr()->literal('sharedWith'),
1054
-				'uid_owner' => $qb->expr()->literal('shareOwner2'),
1055
-				'uid_initiator' => $qb->expr()->literal('sharedBy2'),
1056
-				'item_type' => $qb->expr()->literal('file'),
1057
-				'file_source' => $qb->expr()->literal($fileId2),
1058
-				'file_target' => $qb->expr()->literal('myTarget2'),
1059
-				'permissions' => $qb->expr()->literal(14),
1060
-			]);
1061
-		$this->assertEquals(1, $qb->executeStatement());
1062
-
1063
-		$qb = $this->dbConn->getQueryBuilder();
1064
-		$qb->insert('share')
1065
-			->values([
1066
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1067
-				'share_with' => $qb->expr()->literal('sharedWith'),
1068
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1069
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1070
-				'item_type' => $qb->expr()->literal('file'),
1071
-				'file_source' => $qb->expr()->literal($fileId),
1072
-				'file_target' => $qb->expr()->literal('myTarget'),
1073
-				'permissions' => $qb->expr()->literal(13),
1074
-			]);
1075
-		$this->assertEquals(1, $qb->executeStatement());
1076
-		$id = $qb->getLastInsertId();
1077
-
1078
-		$groups = [];
1079
-		foreach (range(0, 100) as $i) {
1080
-			$groups[] = 'group' . $i;
1081
-		}
1082
-
1083
-		$groups[] = 'sharedWith';
1084
-
1085
-		$user = $this->createMock(IUser::class);
1086
-		$user->method('getUID')->willReturn('sharedWith');
1087
-		$owner = $this->createMock(IUser::class);
1088
-		$owner->method('getUID')->willReturn('shareOwner');
1089
-		$initiator = $this->createMock(IUser::class);
1090
-		$initiator->method('getUID')->willReturn('sharedBy');
1091
-
1092
-		$this->userManager->method('get')->willReturnMap([
1093
-			['sharedWith', $user],
1094
-			['shareOwner', $owner],
1095
-			['sharedBy', $initiator],
1096
-		]);
1097
-		$this->groupManager
1098
-			->method('getUserGroupIds')
1099
-			->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'sharedWith' ? $groups : []));
1100
-
1101
-		$file = $this->createMock(File::class);
1102
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1103
-		$this->rootFolder->method('getFirstNodeById')->with($fileId)->willReturn($file);
1104
-
1105
-		$share = $this->provider->getSharedWith('sharedWith', IShare::TYPE_GROUP, null, 20, 1);
1106
-		$this->assertCount(1, $share);
1107
-
1108
-		$share = $share[0];
1109
-		$this->assertEquals($id, $share->getId());
1110
-		$this->assertEquals('sharedWith', $share->getSharedWith());
1111
-		$this->assertEquals('shareOwner', $share->getShareOwner());
1112
-		$this->assertEquals('sharedBy', $share->getSharedBy());
1113
-		$this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
1114
-	}
1115
-
1116
-	#[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1117
-	public function testGetSharedWithGroupUserModified($storageStringId, $fileName1, $fileName2): void {
1118
-		$storageId = $this->createTestStorageEntry($storageStringId);
1119
-		$fileId = $this->createTestFileEntry($fileName1, $storageId);
1120
-		$qb = $this->dbConn->getQueryBuilder();
1121
-		$qb->insert('share')
1122
-			->values([
1123
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1124
-				'share_with' => $qb->expr()->literal('sharedWith'),
1125
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1126
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1127
-				'item_type' => $qb->expr()->literal('file'),
1128
-				'file_source' => $qb->expr()->literal($fileId),
1129
-				'file_target' => $qb->expr()->literal('myTarget'),
1130
-				'permissions' => $qb->expr()->literal(13),
1131
-			]);
1132
-		$this->assertEquals(1, $qb->executeStatement());
1133
-		$id = $qb->getLastInsertId();
1134
-
1135
-		/*
47
+    /** @var IDBConnection */
48
+    protected $dbConn;
49
+
50
+    /** @var IUserManager | MockObject */
51
+    protected $userManager;
52
+
53
+    /** @var IGroupManager | MockObject */
54
+    protected $groupManager;
55
+
56
+    /** @var IRootFolder | MockObject */
57
+    protected $rootFolder;
58
+
59
+    /** @var DefaultShareProvider */
60
+    protected $provider;
61
+
62
+    /** @var MockObject|IMailer */
63
+    protected $mailer;
64
+
65
+    /** @var IFactory|MockObject */
66
+    protected $l10nFactory;
67
+
68
+    /** @var MockObject|IL10N */
69
+    protected $l10n;
70
+
71
+    /** @var MockObject|Defaults */
72
+    protected $defaults;
73
+
74
+    /** @var MockObject|IURLGenerator */
75
+    protected $urlGenerator;
76
+
77
+    /** @var ITimeFactory|MockObject */
78
+    protected $timeFactory;
79
+
80
+    /** @var LoggerInterface|MockObject */
81
+    protected $logger;
82
+
83
+    protected IConfig&MockObject $config;
84
+
85
+    protected IShareManager&MockObject $shareManager;
86
+
87
+    protected function setUp(): void {
88
+        $this->dbConn = Server::get(IDBConnection::class);
89
+        $this->userManager = $this->createMock(IUserManager::class);
90
+        $this->groupManager = $this->createMock(IGroupManager::class);
91
+        $this->rootFolder = $this->createMock(IRootFolder::class);
92
+        $this->mailer = $this->createMock(IMailer::class);
93
+        $this->l10nFactory = $this->createMock(IFactory::class);
94
+        $this->l10n = $this->createMock(IL10N::class);
95
+        $this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock();
96
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
97
+        $this->timeFactory = $this->createMock(ITimeFactory::class);
98
+        $this->logger = $this->createMock(LoggerInterface::class);
99
+        $this->shareManager = $this->createMock(IShareManager::class);
100
+        $this->config = $this->createMock(IConfig::class);
101
+
102
+        $this->userManager->expects($this->any())->method('userExists')->willReturn(true);
103
+        $this->timeFactory->expects($this->any())->method('now')->willReturn(new \DateTimeImmutable('2023-05-04 00:00 Europe/Berlin'));
104
+
105
+        //Empty share table
106
+        $this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
107
+
108
+        $this->provider = new DefaultShareProvider(
109
+            $this->dbConn,
110
+            $this->userManager,
111
+            $this->groupManager,
112
+            $this->rootFolder,
113
+            $this->mailer,
114
+            $this->defaults,
115
+            $this->l10nFactory,
116
+            $this->urlGenerator,
117
+            $this->timeFactory,
118
+            $this->logger,
119
+            $this->shareManager,
120
+            $this->config,
121
+        );
122
+    }
123
+
124
+    protected function tearDown(): void {
125
+        $this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
126
+        $this->dbConn->getQueryBuilder()->delete('filecache')->runAcrossAllShards()->executeStatement();
127
+        $this->dbConn->getQueryBuilder()->delete('storages')->executeStatement();
128
+    }
129
+
130
+    /**
131
+     * @param int $shareType
132
+     * @param string $sharedWith
133
+     * @param string $sharedBy
134
+     * @param string $shareOwner
135
+     * @param string $itemType
136
+     * @param int $fileSource
137
+     * @param string $fileTarget
138
+     * @param int $permissions
139
+     * @param $token
140
+     * @param $expiration
141
+     * @return int
142
+     */
143
+    private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner,
144
+        $itemType, $fileSource, $fileTarget, $permissions, $token, $expiration,
145
+        $parent = null) {
146
+        $qb = $this->dbConn->getQueryBuilder();
147
+        $qb->insert('share');
148
+
149
+        if ($shareType) {
150
+            $qb->setValue('share_type', $qb->expr()->literal($shareType));
151
+        }
152
+        if ($sharedWith) {
153
+            $qb->setValue('share_with', $qb->expr()->literal($sharedWith));
154
+        }
155
+        if ($sharedBy) {
156
+            $qb->setValue('uid_initiator', $qb->expr()->literal($sharedBy));
157
+        }
158
+        if ($shareOwner) {
159
+            $qb->setValue('uid_owner', $qb->expr()->literal($shareOwner));
160
+        }
161
+        if ($itemType) {
162
+            $qb->setValue('item_type', $qb->expr()->literal($itemType));
163
+        }
164
+        if ($fileSource) {
165
+            $qb->setValue('file_source', $qb->expr()->literal($fileSource));
166
+        }
167
+        if ($fileTarget) {
168
+            $qb->setValue('file_target', $qb->expr()->literal($fileTarget));
169
+        }
170
+        if ($permissions) {
171
+            $qb->setValue('permissions', $qb->expr()->literal($permissions));
172
+        }
173
+        if ($token) {
174
+            $qb->setValue('token', $qb->expr()->literal($token));
175
+        }
176
+        if ($expiration) {
177
+            $qb->setValue('expiration', $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_DATETIME_MUTABLE));
178
+        }
179
+        if ($parent) {
180
+            $qb->setValue('parent', $qb->expr()->literal($parent));
181
+        }
182
+
183
+        $this->assertEquals(1, $qb->executeStatement());
184
+        return $qb->getLastInsertId();
185
+    }
186
+
187
+
188
+
189
+
190
+    public function testGetShareByIdNotExist(): void {
191
+        $this->expectException(ShareNotFound::class);
192
+
193
+        $this->provider->getShareById(1);
194
+    }
195
+
196
+    public function testGetShareByIdUserShare(): void {
197
+        $qb = $this->dbConn->getQueryBuilder();
198
+
199
+        $qb->insert('share')
200
+            ->values([
201
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
202
+                'share_with' => $qb->expr()->literal('sharedWith'),
203
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
204
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
205
+                'item_type' => $qb->expr()->literal('file'),
206
+                'file_source' => $qb->expr()->literal(42),
207
+                'file_target' => $qb->expr()->literal('myTarget'),
208
+                'permissions' => $qb->expr()->literal(13),
209
+            ]);
210
+        $qb->executeStatement();
211
+
212
+        $id = $qb->getLastInsertId();
213
+
214
+        $sharedBy = $this->createMock(IUser::class);
215
+        $sharedBy->method('getUID')->willReturn('sharedBy');
216
+        $shareOwner = $this->createMock(IUser::class);
217
+        $shareOwner->method('getUID')->willReturn('shareOwner');
218
+
219
+        $ownerPath = $this->createMock(File::class);
220
+        $shareOwnerFolder = $this->createMock(Folder::class);
221
+        $shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
222
+
223
+        $this->rootFolder
224
+            ->method('getUserFolder')
225
+            ->willReturnMap([
226
+                ['shareOwner', $shareOwnerFolder],
227
+            ]);
228
+
229
+        $share = $this->provider->getShareById($id);
230
+
231
+        $this->assertEquals($id, $share->getId());
232
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
233
+        $this->assertEquals('sharedWith', $share->getSharedWith());
234
+        $this->assertEquals('sharedBy', $share->getSharedBy());
235
+        $this->assertEquals('shareOwner', $share->getShareOwner());
236
+        $this->assertEquals($ownerPath, $share->getNode());
237
+        $this->assertEquals(13, $share->getPermissions());
238
+        $this->assertEquals(null, $share->getToken());
239
+        $this->assertEquals(null, $share->getExpirationDate());
240
+        $this->assertEquals('myTarget', $share->getTarget());
241
+    }
242
+
243
+    public function testGetShareByIdLazy(): void {
244
+        $qb = $this->dbConn->getQueryBuilder();
245
+
246
+        $qb->insert('share')
247
+            ->values([
248
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
249
+                'share_with' => $qb->expr()->literal('sharedWith'),
250
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
251
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
252
+                'item_type' => $qb->expr()->literal('file'),
253
+                'file_source' => $qb->expr()->literal(42),
254
+                'file_target' => $qb->expr()->literal('myTarget'),
255
+                'permissions' => $qb->expr()->literal(13),
256
+            ]);
257
+        $qb->executeStatement();
258
+
259
+        $id = $qb->getLastInsertId();
260
+
261
+        $this->rootFolder->expects($this->never())->method('getUserFolder');
262
+
263
+        $share = $this->provider->getShareById($id);
264
+
265
+        // We do not fetch the node so the rootfolder is never called.
266
+
267
+        $this->assertEquals($id, $share->getId());
268
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
269
+        $this->assertEquals('sharedWith', $share->getSharedWith());
270
+        $this->assertEquals('sharedBy', $share->getSharedBy());
271
+        $this->assertEquals('shareOwner', $share->getShareOwner());
272
+        $this->assertEquals(13, $share->getPermissions());
273
+        $this->assertEquals(null, $share->getToken());
274
+        $this->assertEquals(null, $share->getExpirationDate());
275
+        $this->assertEquals('myTarget', $share->getTarget());
276
+    }
277
+
278
+    public function testGetShareByIdLazy2(): void {
279
+        $qb = $this->dbConn->getQueryBuilder();
280
+
281
+        $qb->insert('share')
282
+            ->values([
283
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
284
+                'share_with' => $qb->expr()->literal('sharedWith'),
285
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
286
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
287
+                'item_type' => $qb->expr()->literal('file'),
288
+                'file_source' => $qb->expr()->literal(42),
289
+                'file_target' => $qb->expr()->literal('myTarget'),
290
+                'permissions' => $qb->expr()->literal(13),
291
+            ]);
292
+        $qb->executeStatement();
293
+
294
+        $id = $qb->getLastInsertId();
295
+
296
+        $ownerPath = $this->createMock(File::class);
297
+
298
+        $shareOwnerFolder = $this->createMock(Folder::class);
299
+        $shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
300
+
301
+        $this->rootFolder
302
+            ->method('getUserFolder')
303
+            ->with('shareOwner')
304
+            ->willReturn($shareOwnerFolder);
305
+
306
+        $share = $this->provider->getShareById($id);
307
+
308
+        // We fetch the node so the root folder is eventually called
309
+
310
+        $this->assertEquals($id, $share->getId());
311
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
312
+        $this->assertEquals('sharedWith', $share->getSharedWith());
313
+        $this->assertEquals('sharedBy', $share->getSharedBy());
314
+        $this->assertEquals('shareOwner', $share->getShareOwner());
315
+        $this->assertEquals($ownerPath, $share->getNode());
316
+        $this->assertEquals(13, $share->getPermissions());
317
+        $this->assertEquals(null, $share->getToken());
318
+        $this->assertEquals(null, $share->getExpirationDate());
319
+        $this->assertEquals('myTarget', $share->getTarget());
320
+    }
321
+
322
+    public function testGetShareByIdGroupShare(): void {
323
+        $qb = $this->dbConn->getQueryBuilder();
324
+
325
+        $qb->insert('share')
326
+            ->values([
327
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
328
+                'share_with' => $qb->expr()->literal('sharedWith'),
329
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
330
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
331
+                'item_type' => $qb->expr()->literal('file'),
332
+                'file_source' => $qb->expr()->literal(42),
333
+                'file_target' => $qb->expr()->literal('myTarget'),
334
+                'permissions' => $qb->expr()->literal(13),
335
+            ]);
336
+        $this->assertEquals(1, $qb->executeStatement());
337
+
338
+        // Get the id
339
+        $id = $qb->getLastInsertId();
340
+
341
+        $ownerPath = $this->createMock(Folder::class);
342
+        $shareOwnerFolder = $this->createMock(Folder::class);
343
+        $shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
344
+
345
+        $this->rootFolder
346
+            ->method('getUserFolder')
347
+            ->willReturnMap([
348
+                ['shareOwner', $shareOwnerFolder],
349
+            ]);
350
+
351
+        $share = $this->provider->getShareById($id);
352
+
353
+        $this->assertEquals($id, $share->getId());
354
+        $this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
355
+        $this->assertEquals('sharedWith', $share->getSharedWith());
356
+        $this->assertEquals('sharedBy', $share->getSharedBy());
357
+        $this->assertEquals('shareOwner', $share->getShareOwner());
358
+        $this->assertEquals($ownerPath, $share->getNode());
359
+        $this->assertEquals(13, $share->getPermissions());
360
+        $this->assertEquals(null, $share->getToken());
361
+        $this->assertEquals(null, $share->getExpirationDate());
362
+        $this->assertEquals('myTarget', $share->getTarget());
363
+    }
364
+
365
+    public function testGetShareByIdUserGroupShare(): void {
366
+        $id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user0', 'user0', 'file', 42, 'myTarget', 31, null, null);
367
+        $this->addShareToDB(2, 'user1', 'user0', 'user0', 'file', 42, 'userTarget', 0, null, null, $id);
368
+
369
+        $user0 = $this->createMock(IUser::class);
370
+        $user0->method('getUID')->willReturn('user0');
371
+        $user1 = $this->createMock(IUser::class);
372
+        $user1->method('getUID')->willReturn('user1');
373
+
374
+        $group0 = $this->createMock(IGroup::class);
375
+        $group0->method('inGroup')->with($user1)->willReturn(true);
376
+        $group0->method('getDisplayName')->willReturn('g0-displayname');
377
+
378
+        $node = $this->createMock(Folder::class);
379
+        $node->method('getId')->willReturn(42);
380
+        $node->method('getName')->willReturn('myTarget');
381
+
382
+        $this->rootFolder->method('getUserFolder')->with('user0')->willReturnSelf();
383
+        $this->rootFolder->method('getFirstNodeById')->willReturn($node);
384
+
385
+        $this->userManager->method('get')->willReturnMap([
386
+            ['user0', $user0],
387
+            ['user1', $user1],
388
+        ]);
389
+        $this->groupManager->method('get')->with('group0')->willReturn($group0);
390
+
391
+        $share = $this->provider->getShareById($id, 'user1');
392
+
393
+        $this->assertEquals($id, $share->getId());
394
+        $this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
395
+        $this->assertSame('group0', $share->getSharedWith());
396
+        $this->assertSame('user0', $share->getSharedBy());
397
+        $this->assertSame('user0', $share->getShareOwner());
398
+        $this->assertSame($node, $share->getNode());
399
+        $this->assertEquals(0, $share->getPermissions());
400
+        $this->assertEquals(null, $share->getToken());
401
+        $this->assertEquals(null, $share->getExpirationDate());
402
+        $this->assertEquals('userTarget', $share->getTarget());
403
+    }
404
+
405
+    public function testGetShareByIdLinkShare(): void {
406
+        $qb = $this->dbConn->getQueryBuilder();
407
+
408
+        $qb->insert('share')
409
+            ->values([
410
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
411
+                'password' => $qb->expr()->literal('password'),
412
+                'password_by_talk' => $qb->expr()->literal(true),
413
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
414
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
415
+                'item_type' => $qb->expr()->literal('file'),
416
+                'file_source' => $qb->expr()->literal(42),
417
+                'file_target' => $qb->expr()->literal('myTarget'),
418
+                'permissions' => $qb->expr()->literal(13),
419
+                'token' => $qb->expr()->literal('token'),
420
+                'expiration' => $qb->expr()->literal('2000-01-02 00:00:00'),
421
+            ]);
422
+        $this->assertEquals(1, $qb->executeStatement());
423
+
424
+        $id = $qb->getLastInsertId();
425
+
426
+        $ownerPath = $this->createMock(Folder::class);
427
+        $shareOwnerFolder = $this->createMock(Folder::class);
428
+        $shareOwnerFolder->method('getFirstNodeById')->with(42)->willReturn($ownerPath);
429
+
430
+        $this->rootFolder
431
+            ->method('getUserFolder')
432
+            ->willReturnMap([
433
+                ['shareOwner', $shareOwnerFolder],
434
+            ]);
435
+
436
+        $share = $this->provider->getShareById($id);
437
+
438
+        $this->assertEquals($id, $share->getId());
439
+        $this->assertEquals(IShare::TYPE_LINK, $share->getShareType());
440
+        $this->assertNull($share->getSharedWith());
441
+        $this->assertEquals('password', $share->getPassword());
442
+        $this->assertEquals(true, $share->getSendPasswordByTalk());
443
+        $this->assertEquals('sharedBy', $share->getSharedBy());
444
+        $this->assertEquals('shareOwner', $share->getShareOwner());
445
+        $this->assertEquals($ownerPath, $share->getNode());
446
+        $this->assertEquals(13, $share->getPermissions());
447
+        $this->assertEquals('token', $share->getToken());
448
+        $this->assertEquals(\DateTime::createFromFormat('Y-m-d H:i:s', '2000-01-02 00:00:00'), $share->getExpirationDate());
449
+        $this->assertEquals('myTarget', $share->getTarget());
450
+    }
451
+
452
+    public function testDeleteSingleShare(): void {
453
+        $qb = $this->dbConn->getQueryBuilder();
454
+        $qb->insert('share')
455
+            ->values([
456
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
457
+                'share_with' => $qb->expr()->literal('sharedWith'),
458
+                'uid_owner' => $qb->expr()->literal('sharedBy'),
459
+                'item_type' => $qb->expr()->literal('file'),
460
+                'file_source' => $qb->expr()->literal(42),
461
+                'file_target' => $qb->expr()->literal('myTarget'),
462
+                'permissions' => $qb->expr()->literal(13),
463
+            ]);
464
+        $this->assertEquals(1, $qb->executeStatement());
465
+
466
+        $id = $qb->getLastInsertId();
467
+
468
+        $share = $this->createMock(IShare::class);
469
+        $share->method('getId')->willReturn($id);
470
+
471
+        /** @var DefaultShareProvider $provider */
472
+        $provider = $this->getMockBuilder(DefaultShareProvider::class)
473
+            ->setConstructorArgs([
474
+                $this->dbConn,
475
+                $this->userManager,
476
+                $this->groupManager,
477
+                $this->rootFolder,
478
+                $this->mailer,
479
+                $this->defaults,
480
+                $this->l10nFactory,
481
+                $this->urlGenerator,
482
+                $this->timeFactory,
483
+                $this->logger,
484
+                $this->shareManager,
485
+                $this->config,
486
+            ])
487
+            ->onlyMethods(['getShareById'])
488
+            ->getMock();
489
+
490
+        $provider->delete($share);
491
+
492
+        $qb = $this->dbConn->getQueryBuilder();
493
+        $qb->select('*')
494
+            ->from('share');
495
+
496
+        $cursor = $qb->executeQuery();
497
+        $result = $cursor->fetchAll();
498
+        $cursor->closeCursor();
499
+
500
+        $this->assertEmpty($result);
501
+    }
502
+
503
+    public function testDeleteSingleShareLazy(): void {
504
+        $qb = $this->dbConn->getQueryBuilder();
505
+        $qb->insert('share')
506
+            ->values([
507
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
508
+                'share_with' => $qb->expr()->literal('sharedWith'),
509
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
510
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
511
+                'item_type' => $qb->expr()->literal('file'),
512
+                'file_source' => $qb->expr()->literal(42),
513
+                'file_target' => $qb->expr()->literal('myTarget'),
514
+                'permissions' => $qb->expr()->literal(13),
515
+            ]);
516
+        $this->assertEquals(1, $qb->executeStatement());
517
+
518
+        $id = $qb->getLastInsertId();
519
+
520
+        $this->rootFolder->expects($this->never())->method($this->anything());
521
+
522
+        $share = $this->provider->getShareById($id);
523
+        $this->provider->delete($share);
524
+
525
+        $qb = $this->dbConn->getQueryBuilder();
526
+        $qb->select('*')
527
+            ->from('share');
528
+
529
+        $cursor = $qb->executeQuery();
530
+        $result = $cursor->fetchAll();
531
+        $cursor->closeCursor();
532
+
533
+        $this->assertEmpty($result);
534
+    }
535
+
536
+    public function testDeleteGroupShareWithUserGroupShares(): void {
537
+        $qb = $this->dbConn->getQueryBuilder();
538
+        $qb->insert('share')
539
+            ->values([
540
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
541
+                'share_with' => $qb->expr()->literal('sharedWith'),
542
+                'uid_owner' => $qb->expr()->literal('sharedBy'),
543
+                'item_type' => $qb->expr()->literal('file'),
544
+                'file_source' => $qb->expr()->literal(42),
545
+                'file_target' => $qb->expr()->literal('myTarget'),
546
+                'permissions' => $qb->expr()->literal(13),
547
+            ]);
548
+        $this->assertEquals(1, $qb->executeStatement());
549
+        $id = $qb->getLastInsertId();
550
+
551
+        $qb = $this->dbConn->getQueryBuilder();
552
+        $qb->insert('share')
553
+            ->values([
554
+                'share_type' => $qb->expr()->literal(2),
555
+                'share_with' => $qb->expr()->literal('sharedWithUser'),
556
+                'uid_owner' => $qb->expr()->literal('sharedBy'),
557
+                'item_type' => $qb->expr()->literal('file'),
558
+                'file_source' => $qb->expr()->literal(42),
559
+                'file_target' => $qb->expr()->literal('myTarget'),
560
+                'permissions' => $qb->expr()->literal(13),
561
+                'parent' => $qb->expr()->literal($id),
562
+            ]);
563
+        $this->assertEquals(1, $qb->executeStatement());
564
+
565
+        $share = $this->createMock(IShare::class);
566
+        $share->method('getId')->willReturn($id);
567
+        $share->method('getShareType')->willReturn(IShare::TYPE_GROUP);
568
+
569
+        /** @var DefaultShareProvider $provider */
570
+        $provider = $this->getMockBuilder(DefaultShareProvider::class)
571
+            ->setConstructorArgs([
572
+                $this->dbConn,
573
+                $this->userManager,
574
+                $this->groupManager,
575
+                $this->rootFolder,
576
+                $this->mailer,
577
+                $this->defaults,
578
+                $this->l10nFactory,
579
+                $this->urlGenerator,
580
+                $this->timeFactory,
581
+                $this->logger,
582
+                $this->shareManager,
583
+                $this->config,
584
+            ])
585
+            ->onlyMethods(['getShareById'])
586
+            ->getMock();
587
+
588
+        $provider->delete($share);
589
+
590
+        $qb = $this->dbConn->getQueryBuilder();
591
+        $qb->select('*')
592
+            ->from('share');
593
+
594
+        $cursor = $qb->executeQuery();
595
+        $result = $cursor->fetchAll();
596
+        $cursor->closeCursor();
597
+
598
+        $this->assertEmpty($result);
599
+    }
600
+
601
+    public function testGetChildren(): void {
602
+        $qb = $this->dbConn->getQueryBuilder();
603
+        $qb->insert('share')
604
+            ->values([
605
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
606
+                'share_with' => $qb->expr()->literal('sharedWith'),
607
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
608
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
609
+                'item_type' => $qb->expr()->literal('file'),
610
+                'file_source' => $qb->expr()->literal(42),
611
+                'file_target' => $qb->expr()->literal('myTarget'),
612
+                'permissions' => $qb->expr()->literal(13),
613
+            ]);
614
+        $qb->executeStatement();
615
+
616
+        // Get the id
617
+        $id = $qb->getLastInsertId();
618
+
619
+        $qb = $this->dbConn->getQueryBuilder();
620
+        $qb->insert('share')
621
+            ->values([
622
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
623
+                'share_with' => $qb->expr()->literal('user1'),
624
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
625
+                'uid_initiator' => $qb->expr()->literal('user2'),
626
+                'item_type' => $qb->expr()->literal('file'),
627
+                'file_source' => $qb->expr()->literal(1),
628
+                'file_target' => $qb->expr()->literal('myTarget1'),
629
+                'permissions' => $qb->expr()->literal(2),
630
+                'parent' => $qb->expr()->literal($id),
631
+            ]);
632
+        $qb->executeStatement();
633
+
634
+        $qb = $this->dbConn->getQueryBuilder();
635
+        $qb->insert('share')
636
+            ->values([
637
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
638
+                'share_with' => $qb->expr()->literal('group1'),
639
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
640
+                'uid_initiator' => $qb->expr()->literal('user3'),
641
+                'item_type' => $qb->expr()->literal('folder'),
642
+                'file_source' => $qb->expr()->literal(3),
643
+                'file_target' => $qb->expr()->literal('myTarget2'),
644
+                'permissions' => $qb->expr()->literal(4),
645
+                'parent' => $qb->expr()->literal($id),
646
+            ]);
647
+        $qb->executeStatement();
648
+
649
+        $ownerPath = $this->createMock(Folder::class);
650
+        $ownerFolder = $this->createMock(Folder::class);
651
+        $ownerFolder->method('getFirstNodeById')->willReturn($ownerPath);
652
+
653
+        $this->rootFolder
654
+            ->method('getUserFolder')
655
+            ->willReturnMap([
656
+                ['shareOwner', $ownerFolder],
657
+            ]);
658
+
659
+        $share = $this->createMock(IShare::class);
660
+        $share->method('getId')->willReturn($id);
661
+
662
+        $children = $this->provider->getChildren($share);
663
+
664
+        $this->assertCount(2, $children);
665
+
666
+        //Child1
667
+        $this->assertEquals(IShare::TYPE_USER, $children[0]->getShareType());
668
+        $this->assertEquals('user1', $children[0]->getSharedWith());
669
+        $this->assertEquals('user2', $children[0]->getSharedBy());
670
+        $this->assertEquals('shareOwner', $children[0]->getShareOwner());
671
+        $this->assertEquals($ownerPath, $children[0]->getNode());
672
+        $this->assertEquals(2, $children[0]->getPermissions());
673
+        $this->assertEquals(null, $children[0]->getToken());
674
+        $this->assertEquals(null, $children[0]->getExpirationDate());
675
+        $this->assertEquals('myTarget1', $children[0]->getTarget());
676
+
677
+        //Child2
678
+        $this->assertEquals(IShare::TYPE_GROUP, $children[1]->getShareType());
679
+        $this->assertEquals('group1', $children[1]->getSharedWith());
680
+        $this->assertEquals('user3', $children[1]->getSharedBy());
681
+        $this->assertEquals('shareOwner', $children[1]->getShareOwner());
682
+        $this->assertEquals($ownerPath, $children[1]->getNode());
683
+        $this->assertEquals(4, $children[1]->getPermissions());
684
+        $this->assertEquals(null, $children[1]->getToken());
685
+        $this->assertEquals(null, $children[1]->getExpirationDate());
686
+        $this->assertEquals('myTarget2', $children[1]->getTarget());
687
+    }
688
+
689
+    public function testCreateUserShare(): void {
690
+        $share = new Share($this->rootFolder, $this->userManager);
691
+
692
+        $shareOwner = $this->createMock(IUser::class);
693
+        $shareOwner->method('getUID')->willReturn('shareOwner');
694
+
695
+        $path = $this->createMock(File::class);
696
+        $path->method('getId')->willReturn(100);
697
+        $path->method('getOwner')->willReturn($shareOwner);
698
+
699
+        $ownerFolder = $this->createMock(Folder::class);
700
+        $userFolder = $this->createMock(Folder::class);
701
+        $this->rootFolder
702
+            ->method('getUserFolder')
703
+            ->willReturnMap([
704
+                ['sharedBy', $userFolder],
705
+                ['shareOwner', $ownerFolder],
706
+            ]);
707
+
708
+        $userFolder->method('getFirstNodeById')
709
+            ->with(100)
710
+            ->willReturn($path);
711
+        $ownerFolder->method('getFirstNodeById')
712
+            ->with(100)
713
+            ->willReturn($path);
714
+
715
+        $share->setShareType(IShare::TYPE_USER);
716
+        $share->setSharedWith('sharedWith');
717
+        $share->setSharedBy('sharedBy');
718
+        $share->setShareOwner('shareOwner');
719
+        $share->setNode($path);
720
+        $share->setSharedWithDisplayName('Displayed Name');
721
+        $share->setSharedWithAvatar('/path/to/image.svg');
722
+        $share->setPermissions(1);
723
+
724
+        $attrs = new ShareAttributes();
725
+        $attrs->setAttribute('permissions', 'download', true);
726
+        $share->setAttributes($attrs);
727
+
728
+        $share->setTarget('/target');
729
+
730
+        $share2 = $this->provider->create($share);
731
+
732
+        $this->assertNotNull($share2->getId());
733
+        $this->assertSame('ocinternal:' . $share2->getId(), $share2->getFullId());
734
+        $this->assertSame(IShare::TYPE_USER, $share2->getShareType());
735
+        $this->assertSame('sharedWith', $share2->getSharedWith());
736
+        $this->assertSame('sharedBy', $share2->getSharedBy());
737
+        $this->assertSame('shareOwner', $share2->getShareOwner());
738
+        $this->assertSame(1, $share2->getPermissions());
739
+        $this->assertSame('/target', $share2->getTarget());
740
+        $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime());
741
+        $this->assertSame($path, $share2->getNode());
742
+
743
+        // Data is kept after creation
744
+        $this->assertSame('Displayed Name', $share->getSharedWithDisplayName());
745
+        $this->assertSame('/path/to/image.svg', $share->getSharedWithAvatar());
746
+        $this->assertSame('Displayed Name', $share2->getSharedWithDisplayName());
747
+        $this->assertSame('/path/to/image.svg', $share2->getSharedWithAvatar());
748
+
749
+        $this->assertSame(
750
+            [
751
+                [
752
+                    'scope' => 'permissions',
753
+                    'key' => 'download',
754
+                    'value' => true
755
+                ]
756
+            ],
757
+            $share->getAttributes()->toArray()
758
+        );
759
+    }
760
+
761
+    public function testCreateGroupShare(): void {
762
+        $share = new Share($this->rootFolder, $this->userManager);
763
+
764
+        $shareOwner = $this->createMock(IUser::class);
765
+        $shareOwner->method('getUID')->willReturn('shareOwner');
766
+
767
+        $path = $this->createMock(Folder::class);
768
+        $path->method('getId')->willReturn(100);
769
+        $path->method('getOwner')->willReturn($shareOwner);
770
+
771
+        $ownerFolder = $this->createMock(Folder::class);
772
+        $userFolder = $this->createMock(Folder::class);
773
+        $this->rootFolder
774
+            ->method('getUserFolder')
775
+            ->willReturnMap([
776
+                ['sharedBy', $userFolder],
777
+                ['shareOwner', $ownerFolder],
778
+            ]);
779
+
780
+        $userFolder->method('getFirstNodeById')
781
+            ->with(100)
782
+            ->willReturn($path);
783
+        $ownerFolder->method('getFirstNodeById')
784
+            ->with(100)
785
+            ->willReturn($path);
786
+
787
+        $share->setShareType(IShare::TYPE_GROUP);
788
+        $share->setSharedWith('sharedWith');
789
+        $share->setSharedBy('sharedBy');
790
+        $share->setShareOwner('shareOwner');
791
+        $share->setNode($path);
792
+        $share->setPermissions(1);
793
+        $share->setSharedWithDisplayName('Displayed Name');
794
+        $share->setSharedWithAvatar('/path/to/image.svg');
795
+        $share->setTarget('/target');
796
+        $attrs = new ShareAttributes();
797
+        $attrs->setAttribute('permissions', 'download', true);
798
+        $share->setAttributes($attrs);
799
+
800
+        $share2 = $this->provider->create($share);
801
+
802
+        $this->assertNotNull($share2->getId());
803
+        $this->assertSame('ocinternal:' . $share2->getId(), $share2->getFullId());
804
+        $this->assertSame(IShare::TYPE_GROUP, $share2->getShareType());
805
+        $this->assertSame('sharedWith', $share2->getSharedWith());
806
+        $this->assertSame('sharedBy', $share2->getSharedBy());
807
+        $this->assertSame('shareOwner', $share2->getShareOwner());
808
+        $this->assertSame(1, $share2->getPermissions());
809
+        $this->assertSame('/target', $share2->getTarget());
810
+        $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime());
811
+        $this->assertSame($path, $share2->getNode());
812
+
813
+        // Data is kept after creation
814
+        $this->assertSame('Displayed Name', $share->getSharedWithDisplayName());
815
+        $this->assertSame('/path/to/image.svg', $share->getSharedWithAvatar());
816
+        $this->assertSame('Displayed Name', $share2->getSharedWithDisplayName());
817
+        $this->assertSame('/path/to/image.svg', $share2->getSharedWithAvatar());
818
+
819
+        $this->assertSame(
820
+            [
821
+                [
822
+                    'scope' => 'permissions',
823
+                    'key' => 'download',
824
+                    'value' => true
825
+                ]
826
+            ],
827
+            $share->getAttributes()->toArray()
828
+        );
829
+    }
830
+
831
+    public function testCreateLinkShare(): void {
832
+        $share = new Share($this->rootFolder, $this->userManager);
833
+
834
+        $shareOwner = $this->createMock(IUser::class);
835
+        $shareOwner->method('getUID')->willReturn('shareOwner');
836
+
837
+        $path = $this->createMock(Folder::class);
838
+        $path->method('getId')->willReturn(100);
839
+        $path->method('getOwner')->willReturn($shareOwner);
840
+
841
+        $ownerFolder = $this->createMock(Folder::class);
842
+        $userFolder = $this->createMock(Folder::class);
843
+        $this->rootFolder
844
+            ->method('getUserFolder')
845
+            ->willReturnMap([
846
+                ['sharedBy', $userFolder],
847
+                ['shareOwner', $ownerFolder],
848
+            ]);
849
+
850
+        $userFolder->method('getFirstNodeById')
851
+            ->with(100)
852
+            ->willReturn($path);
853
+        $ownerFolder->method('getFirstNodeById')
854
+            ->with(100)
855
+            ->willReturn($path);
856
+
857
+        $share->setShareType(IShare::TYPE_LINK);
858
+        $share->setSharedBy('sharedBy');
859
+        $share->setShareOwner('shareOwner');
860
+        $share->setNode($path);
861
+        $share->setPermissions(1);
862
+        $share->setPassword('password');
863
+        $share->setSendPasswordByTalk(true);
864
+        $share->setToken('token');
865
+        $expireDate = new \DateTime();
866
+        $share->setExpirationDate($expireDate);
867
+        $share->setTarget('/target');
868
+
869
+        $share2 = $this->provider->create($share);
870
+
871
+        $this->assertNotNull($share2->getId());
872
+        $this->assertSame('ocinternal:' . $share2->getId(), $share2->getFullId());
873
+        $this->assertSame(IShare::TYPE_LINK, $share2->getShareType());
874
+        $this->assertSame('sharedBy', $share2->getSharedBy());
875
+        $this->assertSame('shareOwner', $share2->getShareOwner());
876
+        $this->assertSame(1, $share2->getPermissions());
877
+        $this->assertSame('/target', $share2->getTarget());
878
+        $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime());
879
+        $this->assertSame($path, $share2->getNode());
880
+        $this->assertSame('password', $share2->getPassword());
881
+        $this->assertSame(true, $share2->getSendPasswordByTalk());
882
+        $this->assertSame('token', $share2->getToken());
883
+        $this->assertEquals($expireDate->getTimestamp(), $share2->getExpirationDate()->getTimestamp());
884
+    }
885
+
886
+    public function testGetShareByToken(): void {
887
+        $qb = $this->dbConn->getQueryBuilder();
888
+
889
+        $qb->insert('share')
890
+            ->values([
891
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
892
+                'password' => $qb->expr()->literal('password'),
893
+                'password_by_talk' => $qb->expr()->literal(true),
894
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
895
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
896
+                'item_type' => $qb->expr()->literal('file'),
897
+                'file_source' => $qb->expr()->literal(42),
898
+                'file_target' => $qb->expr()->literal('myTarget'),
899
+                'permissions' => $qb->expr()->literal(13),
900
+                'token' => $qb->expr()->literal('secrettoken'),
901
+                'label' => $qb->expr()->literal('the label'),
902
+            ]);
903
+        $qb->executeStatement();
904
+        $id = $qb->getLastInsertId();
905
+
906
+        $file = $this->createMock(File::class);
907
+
908
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
909
+        $this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
910
+
911
+        $share = $this->provider->getShareByToken('secrettoken');
912
+        $this->assertEquals($id, $share->getId());
913
+        $this->assertSame('shareOwner', $share->getShareOwner());
914
+        $this->assertSame('sharedBy', $share->getSharedBy());
915
+        $this->assertSame('secrettoken', $share->getToken());
916
+        $this->assertSame('password', $share->getPassword());
917
+        $this->assertSame('the label', $share->getLabel());
918
+        $this->assertSame(true, $share->getSendPasswordByTalk());
919
+        $this->assertSame(null, $share->getSharedWith());
920
+    }
921
+
922
+    /**
923
+     * Assert that if no label is provided the label is correctly,
924
+     * as types on IShare, a string and not null
925
+     */
926
+    public function testGetShareByTokenNullLabel(): void {
927
+        $qb = $this->dbConn->getQueryBuilder();
928
+
929
+        $qb->insert('share')
930
+            ->values([
931
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
932
+                'password' => $qb->expr()->literal('password'),
933
+                'password_by_talk' => $qb->expr()->literal(true),
934
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
935
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
936
+                'item_type' => $qb->expr()->literal('file'),
937
+                'file_source' => $qb->expr()->literal(42),
938
+                'file_target' => $qb->expr()->literal('myTarget'),
939
+                'permissions' => $qb->expr()->literal(13),
940
+                'token' => $qb->expr()->literal('secrettoken'),
941
+            ]);
942
+        $qb->executeStatement();
943
+        $id = $qb->getLastInsertId();
944
+
945
+        $file = $this->createMock(File::class);
946
+
947
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
948
+        $this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
949
+
950
+        $share = $this->provider->getShareByToken('secrettoken');
951
+        $this->assertEquals($id, $share->getId());
952
+        $this->assertSame('', $share->getLabel());
953
+    }
954
+
955
+    public function testGetShareByTokenNotFound(): void {
956
+        $this->expectException(ShareNotFound::class);
957
+
958
+        $this->provider->getShareByToken('invalidtoken');
959
+    }
960
+
961
+    private function createTestStorageEntry($storageStringId) {
962
+        $qb = $this->dbConn->getQueryBuilder();
963
+        $qb->insert('storages')
964
+            ->values([
965
+                'id' => $qb->expr()->literal($storageStringId),
966
+            ]);
967
+        $this->assertEquals(1, $qb->executeStatement());
968
+        return $qb->getLastInsertId();
969
+    }
970
+
971
+    private function createTestFileEntry($path, $storage = 1) {
972
+        $qb = $this->dbConn->getQueryBuilder();
973
+        $qb->insert('filecache')
974
+            ->values([
975
+                'storage' => $qb->createNamedParameter($storage, IQueryBuilder::PARAM_INT),
976
+                'path' => $qb->createNamedParameter($path),
977
+                'path_hash' => $qb->createNamedParameter(md5($path)),
978
+                'name' => $qb->createNamedParameter(basename($path)),
979
+            ]);
980
+        $this->assertEquals(1, $qb->executeStatement());
981
+        return $qb->getLastInsertId();
982
+    }
983
+
984
+    public static function storageAndFileNameProvider(): array {
985
+        return [
986
+            // regular file on regular storage
987
+            ['home::shareOwner', 'files/test.txt', 'files/test2.txt'],
988
+            // regular file on external storage
989
+            ['smb::whatever', 'files/test.txt', 'files/test2.txt'],
990
+            // regular file on external storage in trashbin-like folder,
991
+            ['smb::whatever', 'files_trashbin/files/test.txt', 'files_trashbin/files/test2.txt'],
992
+        ];
993
+    }
994
+
995
+    #[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
996
+    public function testGetSharedWithUser($storageStringId, $fileName1, $fileName2): void {
997
+        $storageId = $this->createTestStorageEntry($storageStringId);
998
+        $fileId = $this->createTestFileEntry($fileName1, $storageId);
999
+        $fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1000
+        $qb = $this->dbConn->getQueryBuilder();
1001
+        $qb->insert('share')
1002
+            ->values([
1003
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1004
+                'share_with' => $qb->expr()->literal('sharedWith'),
1005
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1006
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1007
+                'item_type' => $qb->expr()->literal('file'),
1008
+                'file_source' => $qb->expr()->literal($fileId),
1009
+                'file_target' => $qb->expr()->literal('myTarget'),
1010
+                'permissions' => $qb->expr()->literal(13),
1011
+            ]);
1012
+        $this->assertEquals(1, $qb->executeStatement());
1013
+        $id = $qb->getLastInsertId();
1014
+
1015
+        $qb = $this->dbConn->getQueryBuilder();
1016
+        $qb->insert('share')
1017
+            ->values([
1018
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1019
+                'share_with' => $qb->expr()->literal('sharedWith2'),
1020
+                'uid_owner' => $qb->expr()->literal('shareOwner2'),
1021
+                'uid_initiator' => $qb->expr()->literal('sharedBy2'),
1022
+                'item_type' => $qb->expr()->literal('file2'),
1023
+                'file_source' => $qb->expr()->literal($fileId2),
1024
+                'file_target' => $qb->expr()->literal('myTarget2'),
1025
+                'permissions' => $qb->expr()->literal(14),
1026
+            ]);
1027
+        $this->assertEquals(1, $qb->executeStatement());
1028
+
1029
+        $file = $this->createMock(File::class);
1030
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1031
+        $this->rootFolder->method('getFirstNodeById')->with($fileId)->willReturn($file);
1032
+
1033
+        $share = $this->provider->getSharedWith('sharedWith', IShare::TYPE_USER, null, 1, 0);
1034
+        $this->assertCount(1, $share);
1035
+
1036
+        $share = $share[0];
1037
+        $this->assertEquals($id, $share->getId());
1038
+        $this->assertEquals('sharedWith', $share->getSharedWith());
1039
+        $this->assertEquals('shareOwner', $share->getShareOwner());
1040
+        $this->assertEquals('sharedBy', $share->getSharedBy());
1041
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1042
+    }
1043
+
1044
+    #[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1045
+    public function testGetSharedWithGroup($storageStringId, $fileName1, $fileName2): void {
1046
+        $storageId = $this->createTestStorageEntry($storageStringId);
1047
+        $fileId = $this->createTestFileEntry($fileName1, $storageId);
1048
+        $fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1049
+        $qb = $this->dbConn->getQueryBuilder();
1050
+        $qb->insert('share')
1051
+            ->values([
1052
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1053
+                'share_with' => $qb->expr()->literal('sharedWith'),
1054
+                'uid_owner' => $qb->expr()->literal('shareOwner2'),
1055
+                'uid_initiator' => $qb->expr()->literal('sharedBy2'),
1056
+                'item_type' => $qb->expr()->literal('file'),
1057
+                'file_source' => $qb->expr()->literal($fileId2),
1058
+                'file_target' => $qb->expr()->literal('myTarget2'),
1059
+                'permissions' => $qb->expr()->literal(14),
1060
+            ]);
1061
+        $this->assertEquals(1, $qb->executeStatement());
1062
+
1063
+        $qb = $this->dbConn->getQueryBuilder();
1064
+        $qb->insert('share')
1065
+            ->values([
1066
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1067
+                'share_with' => $qb->expr()->literal('sharedWith'),
1068
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1069
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1070
+                'item_type' => $qb->expr()->literal('file'),
1071
+                'file_source' => $qb->expr()->literal($fileId),
1072
+                'file_target' => $qb->expr()->literal('myTarget'),
1073
+                'permissions' => $qb->expr()->literal(13),
1074
+            ]);
1075
+        $this->assertEquals(1, $qb->executeStatement());
1076
+        $id = $qb->getLastInsertId();
1077
+
1078
+        $groups = [];
1079
+        foreach (range(0, 100) as $i) {
1080
+            $groups[] = 'group' . $i;
1081
+        }
1082
+
1083
+        $groups[] = 'sharedWith';
1084
+
1085
+        $user = $this->createMock(IUser::class);
1086
+        $user->method('getUID')->willReturn('sharedWith');
1087
+        $owner = $this->createMock(IUser::class);
1088
+        $owner->method('getUID')->willReturn('shareOwner');
1089
+        $initiator = $this->createMock(IUser::class);
1090
+        $initiator->method('getUID')->willReturn('sharedBy');
1091
+
1092
+        $this->userManager->method('get')->willReturnMap([
1093
+            ['sharedWith', $user],
1094
+            ['shareOwner', $owner],
1095
+            ['sharedBy', $initiator],
1096
+        ]);
1097
+        $this->groupManager
1098
+            ->method('getUserGroupIds')
1099
+            ->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'sharedWith' ? $groups : []));
1100
+
1101
+        $file = $this->createMock(File::class);
1102
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1103
+        $this->rootFolder->method('getFirstNodeById')->with($fileId)->willReturn($file);
1104
+
1105
+        $share = $this->provider->getSharedWith('sharedWith', IShare::TYPE_GROUP, null, 20, 1);
1106
+        $this->assertCount(1, $share);
1107
+
1108
+        $share = $share[0];
1109
+        $this->assertEquals($id, $share->getId());
1110
+        $this->assertEquals('sharedWith', $share->getSharedWith());
1111
+        $this->assertEquals('shareOwner', $share->getShareOwner());
1112
+        $this->assertEquals('sharedBy', $share->getSharedBy());
1113
+        $this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
1114
+    }
1115
+
1116
+    #[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1117
+    public function testGetSharedWithGroupUserModified($storageStringId, $fileName1, $fileName2): void {
1118
+        $storageId = $this->createTestStorageEntry($storageStringId);
1119
+        $fileId = $this->createTestFileEntry($fileName1, $storageId);
1120
+        $qb = $this->dbConn->getQueryBuilder();
1121
+        $qb->insert('share')
1122
+            ->values([
1123
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1124
+                'share_with' => $qb->expr()->literal('sharedWith'),
1125
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1126
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1127
+                'item_type' => $qb->expr()->literal('file'),
1128
+                'file_source' => $qb->expr()->literal($fileId),
1129
+                'file_target' => $qb->expr()->literal('myTarget'),
1130
+                'permissions' => $qb->expr()->literal(13),
1131
+            ]);
1132
+        $this->assertEquals(1, $qb->executeStatement());
1133
+        $id = $qb->getLastInsertId();
1134
+
1135
+        /*
1136 1136
 		 * Wrong share. Should not be taken by code.
1137 1137
 		 */
1138
-		$qb = $this->dbConn->getQueryBuilder();
1139
-		$qb->insert('share')
1140
-			->values([
1141
-				'share_type' => $qb->expr()->literal(2),
1142
-				'share_with' => $qb->expr()->literal('user2'),
1143
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1144
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1145
-				'item_type' => $qb->expr()->literal('file'),
1146
-				'file_source' => $qb->expr()->literal($fileId),
1147
-				'file_target' => $qb->expr()->literal('wrongTarget'),
1148
-				'permissions' => $qb->expr()->literal(31),
1149
-				'parent' => $qb->expr()->literal($id),
1150
-			]);
1151
-		$this->assertEquals(1, $qb->executeStatement());
1152
-
1153
-		/*
1138
+        $qb = $this->dbConn->getQueryBuilder();
1139
+        $qb->insert('share')
1140
+            ->values([
1141
+                'share_type' => $qb->expr()->literal(2),
1142
+                'share_with' => $qb->expr()->literal('user2'),
1143
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1144
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1145
+                'item_type' => $qb->expr()->literal('file'),
1146
+                'file_source' => $qb->expr()->literal($fileId),
1147
+                'file_target' => $qb->expr()->literal('wrongTarget'),
1148
+                'permissions' => $qb->expr()->literal(31),
1149
+                'parent' => $qb->expr()->literal($id),
1150
+            ]);
1151
+        $this->assertEquals(1, $qb->executeStatement());
1152
+
1153
+        /*
1154 1154
 		 * Correct share. should be taken by code path.
1155 1155
 		 */
1156
-		$qb = $this->dbConn->getQueryBuilder();
1157
-		$qb->insert('share')
1158
-			->values([
1159
-				'share_type' => $qb->expr()->literal(2),
1160
-				'share_with' => $qb->expr()->literal('user'),
1161
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1162
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1163
-				'item_type' => $qb->expr()->literal('file'),
1164
-				'file_source' => $qb->expr()->literal($fileId),
1165
-				'file_target' => $qb->expr()->literal('userTarget'),
1166
-				'permissions' => $qb->expr()->literal(0),
1167
-				'parent' => $qb->expr()->literal($id),
1168
-			]);
1169
-		$this->assertEquals(1, $qb->executeStatement());
1170
-
1171
-		$groups = ['sharedWith'];
1172
-
1173
-		$user = $this->createMock(IUser::class);
1174
-		$user->method('getUID')->willReturn('user');
1175
-		$owner = $this->createMock(IUser::class);
1176
-		$owner->method('getUID')->willReturn('shareOwner');
1177
-		$initiator = $this->createMock(IUser::class);
1178
-		$initiator->method('getUID')->willReturn('sharedBy');
1179
-
1180
-		$this->userManager->method('get')->willReturnMap([
1181
-			['user', $user],
1182
-			['shareOwner', $owner],
1183
-			['sharedBy', $initiator],
1184
-		]);
1185
-		$this->groupManager
1186
-			->method('getUserGroupIds')
1187
-			->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'user' ? $groups : []));
1188
-
1189
-		$file = $this->createMock(File::class);
1190
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1191
-		$this->rootFolder->method('getFirstNodeById')->with($fileId)->willReturn($file);
1192
-
1193
-		$share = $this->provider->getSharedWith('user', IShare::TYPE_GROUP, null, -1, 0);
1194
-		$this->assertCount(1, $share);
1195
-
1196
-		$share = $share[0];
1197
-		$this->assertSame((string)$id, $share->getId());
1198
-		$this->assertSame('sharedWith', $share->getSharedWith());
1199
-		$this->assertSame('shareOwner', $share->getShareOwner());
1200
-		$this->assertSame('sharedBy', $share->getSharedBy());
1201
-		$this->assertSame(IShare::TYPE_GROUP, $share->getShareType());
1202
-		$this->assertSame(0, $share->getPermissions());
1203
-		$this->assertSame('userTarget', $share->getTarget());
1204
-	}
1205
-
1206
-	#[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1207
-	public function testGetSharedWithUserWithNode($storageStringId, $fileName1, $fileName2): void {
1208
-		$storageId = $this->createTestStorageEntry($storageStringId);
1209
-		$fileId = $this->createTestFileEntry($fileName1, $storageId);
1210
-		$fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1211
-		$this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user1',
1212
-			'file', $fileId, 'myTarget', 31, null, null, null);
1213
-		$id = $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user1',
1214
-			'file', $fileId2, 'myTarget', 31, null, null, null);
1215
-
1216
-		$user0 = $this->createMock(IUser::class);
1217
-		$user0->method('getUID')->willReturn('user0');
1218
-		$user0->method('getDisplayName')->willReturn('user0');
1219
-		$user1 = $this->createMock(IUser::class);
1220
-		$user1->method('getUID')->willReturn('user1');
1221
-		$user0->method('getDisplayName')->willReturn('user0');
1222
-
1223
-		$this->userManager->method('get')->willReturnMap([
1224
-			['user0', $user0],
1225
-			['user1', $user1],
1226
-		]);
1227
-
1228
-		$file = $this->createMock(File::class);
1229
-		$file->method('getId')->willReturn($fileId2);
1230
-
1231
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1232
-		$this->rootFolder->method('getFirstNodeById')->with($fileId2)->willReturn($file);
1233
-
1234
-		$share = $this->provider->getSharedWith('user0', IShare::TYPE_USER, $file, -1, 0);
1235
-		$this->assertCount(1, $share);
1236
-
1237
-		$share = $share[0];
1238
-		$this->assertEquals($id, $share->getId());
1239
-		$this->assertSame('user0', $share->getSharedWith());
1240
-		$this->assertSame('user1', $share->getShareOwner());
1241
-		$this->assertSame('user1', $share->getSharedBy());
1242
-		$this->assertSame($file, $share->getNode());
1243
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1244
-	}
1245
-
1246
-	#[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1247
-	public function testGetSharedWithGroupWithNode($storageStringId, $fileName1, $fileName2): void {
1248
-		$storageId = $this->createTestStorageEntry($storageStringId);
1249
-		$fileId = $this->createTestFileEntry($fileName1, $storageId);
1250
-		$fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1251
-		$this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user1',
1252
-			'file', $fileId, 'myTarget', 31, null, null, null);
1253
-		$id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user1',
1254
-			'file', $fileId2, 'myTarget', 31, null, null, null);
1255
-
1256
-		$user0 = $this->createMock(IUser::class);
1257
-		$user0->method('getUID')->willReturn('user0');
1258
-		$user1 = $this->createMock(IUser::class);
1259
-		$user1->method('getUID')->willReturn('user1');
1260
-
1261
-		$this->userManager->method('get')->willReturnMap([
1262
-			['user0', $user0],
1263
-			['user1', $user1],
1264
-		]);
1265
-
1266
-		$this->groupManager
1267
-			->method('getUserGroupIds')
1268
-			->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'user0' ? ['group0'] : []));
1269
-
1270
-		$node = $this->createMock(Folder::class);
1271
-		$node->method('getId')->willReturn($fileId2);
1272
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1273
-		$this->rootFolder->method('getFirstNodeById')->with($fileId2)->willReturn($node);
1274
-
1275
-		$share = $this->provider->getSharedWith('user0', IShare::TYPE_GROUP, $node, -1, 0);
1276
-		$this->assertCount(1, $share);
1277
-
1278
-		$share = $share[0];
1279
-		$this->assertEquals($id, $share->getId());
1280
-		$this->assertSame('group0', $share->getSharedWith());
1281
-		$this->assertSame('user1', $share->getShareOwner());
1282
-		$this->assertSame('user1', $share->getSharedBy());
1283
-		$this->assertSame($node, $share->getNode());
1284
-		$this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
1285
-	}
1286
-
1287
-	public static function shareTypesProvider(): array {
1288
-		return [
1289
-			[IShare::TYPE_USER, false],
1290
-			[IShare::TYPE_GROUP, false],
1291
-			[IShare::TYPE_USER, true],
1292
-			[IShare::TYPE_GROUP, true],
1293
-		];
1294
-	}
1295
-
1296
-	#[\PHPUnit\Framework\Attributes\DataProvider('shareTypesProvider')]
1297
-	public function testGetSharedWithWithDeletedFile($shareType, $trashed): void {
1298
-		if ($trashed) {
1299
-			// exists in database but is in trash
1300
-			$storageId = $this->createTestStorageEntry('home::shareOwner');
1301
-			$deletedFileId = $this->createTestFileEntry('files_trashbin/files/test.txt.d1465553223', $storageId);
1302
-		} else {
1303
-			// fileid that doesn't exist in the database
1304
-			$deletedFileId = 123;
1305
-		}
1306
-		$qb = $this->dbConn->getQueryBuilder();
1307
-		$qb->insert('share')
1308
-			->values([
1309
-				'share_type' => $qb->expr()->literal($shareType),
1310
-				'share_with' => $qb->expr()->literal('sharedWith'),
1311
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1312
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1313
-				'item_type' => $qb->expr()->literal('file'),
1314
-				'file_source' => $qb->expr()->literal($deletedFileId),
1315
-				'file_target' => $qb->expr()->literal('myTarget'),
1316
-				'permissions' => $qb->expr()->literal(13),
1317
-			]);
1318
-		$this->assertEquals(1, $qb->executeStatement());
1319
-
1320
-		$file = $this->createMock(File::class);
1321
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1322
-		$this->rootFolder->method('getFirstNodeById')->with($deletedFileId)->willReturn($file);
1323
-
1324
-		$groups = [];
1325
-		foreach (range(0, 100) as $i) {
1326
-			$groups[] = 'group' . $i;
1327
-		}
1328
-
1329
-		$groups[] = 'sharedWith';
1330
-
1331
-		$user = $this->createMock(IUser::class);
1332
-		$user->method('getUID')->willReturn('sharedWith');
1333
-		$owner = $this->createMock(IUser::class);
1334
-		$owner->method('getUID')->willReturn('shareOwner');
1335
-		$initiator = $this->createMock(IUser::class);
1336
-		$initiator->method('getUID')->willReturn('sharedBy');
1337
-
1338
-		$this->userManager->method('get')->willReturnMap([
1339
-			['sharedWith', $user],
1340
-			['shareOwner', $owner],
1341
-			['sharedBy', $initiator],
1342
-		]);
1343
-		$this->groupManager
1344
-			->method('getUserGroupIds')
1345
-			->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'sharedWith' ? $groups : []));
1346
-
1347
-		$share = $this->provider->getSharedWith('sharedWith', $shareType, null, 1, 0);
1348
-		$this->assertCount(0, $share);
1349
-	}
1350
-
1351
-	public function testGetSharesBy(): void {
1352
-		$qb = $this->dbConn->getQueryBuilder();
1353
-		$qb->insert('share')
1354
-			->values([
1355
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1356
-				'share_with' => $qb->expr()->literal('sharedWith'),
1357
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1358
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1359
-				'item_type' => $qb->expr()->literal('file'),
1360
-				'file_source' => $qb->expr()->literal(42),
1361
-				'file_target' => $qb->expr()->literal('myTarget'),
1362
-				'permissions' => $qb->expr()->literal(13),
1363
-			]);
1364
-		$this->assertEquals(1, $qb->executeStatement());
1365
-		$id = $qb->getLastInsertId();
1366
-
1367
-		$qb = $this->dbConn->getQueryBuilder();
1368
-		$qb->insert('share')
1369
-			->values([
1370
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1371
-				'share_with' => $qb->expr()->literal('sharedWith'),
1372
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1373
-				'uid_initiator' => $qb->expr()->literal('sharedBy2'),
1374
-				'item_type' => $qb->expr()->literal('file'),
1375
-				'file_source' => $qb->expr()->literal(42),
1376
-				'file_target' => $qb->expr()->literal('userTarget'),
1377
-				'permissions' => $qb->expr()->literal(0),
1378
-				'parent' => $qb->expr()->literal($id),
1379
-			]);
1380
-		$this->assertEquals(1, $qb->executeStatement());
1381
-
1382
-		$file = $this->createMock(File::class);
1383
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1384
-		$this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
1385
-
1386
-		$share = $this->provider->getSharesBy('sharedBy', IShare::TYPE_USER, null, false, 1, 0);
1387
-		$this->assertCount(1, $share);
1388
-
1389
-		/** @var IShare $share */
1390
-		$share = $share[0];
1391
-		$this->assertEquals($id, $share->getId());
1392
-		$this->assertEquals('sharedWith', $share->getSharedWith());
1393
-		$this->assertEquals('shareOwner', $share->getShareOwner());
1394
-		$this->assertEquals('sharedBy', $share->getSharedBy());
1395
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1396
-		$this->assertEquals(13, $share->getPermissions());
1397
-		$this->assertEquals('myTarget', $share->getTarget());
1398
-	}
1399
-
1400
-	public function testGetSharesNode(): void {
1401
-		$qb = $this->dbConn->getQueryBuilder();
1402
-		$qb->insert('share')
1403
-			->values([
1404
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1405
-				'share_with' => $qb->expr()->literal('sharedWith'),
1406
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1407
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1408
-				'item_type' => $qb->expr()->literal('file'),
1409
-				'file_source' => $qb->expr()->literal(42),
1410
-				'file_target' => $qb->expr()->literal('myTarget'),
1411
-				'permissions' => $qb->expr()->literal(13),
1412
-			]);
1413
-		$this->assertEquals(1, $qb->executeStatement());
1414
-		$id = $qb->getLastInsertId();
1415
-
1416
-		$qb = $this->dbConn->getQueryBuilder();
1417
-		$qb->insert('share')
1418
-			->values([
1419
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1420
-				'share_with' => $qb->expr()->literal('sharedWith'),
1421
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1422
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1423
-				'item_type' => $qb->expr()->literal('file'),
1424
-				'file_source' => $qb->expr()->literal(43),
1425
-				'file_target' => $qb->expr()->literal('userTarget'),
1426
-				'permissions' => $qb->expr()->literal(0),
1427
-				'parent' => $qb->expr()->literal($id),
1428
-			]);
1429
-		$this->assertEquals(1, $qb->executeStatement());
1430
-
1431
-		$file = $this->createMock(File::class);
1432
-		$file->method('getId')->willReturn(42);
1433
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1434
-		$this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
1435
-
1436
-		$share = $this->provider->getSharesBy('sharedBy', IShare::TYPE_USER, $file, false, 1, 0);
1437
-		$this->assertCount(1, $share);
1438
-
1439
-		/** @var IShare $share */
1440
-		$share = $share[0];
1441
-		$this->assertEquals($id, $share->getId());
1442
-		$this->assertEquals('sharedWith', $share->getSharedWith());
1443
-		$this->assertEquals('shareOwner', $share->getShareOwner());
1444
-		$this->assertEquals('sharedBy', $share->getSharedBy());
1445
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1446
-		$this->assertEquals(13, $share->getPermissions());
1447
-		$this->assertEquals('myTarget', $share->getTarget());
1448
-	}
1449
-
1450
-	public function testGetSharesReshare(): void {
1451
-		$qb = $this->dbConn->getQueryBuilder();
1452
-		$qb->insert('share')
1453
-			->values([
1454
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1455
-				'share_with' => $qb->expr()->literal('sharedWith'),
1456
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1457
-				'uid_initiator' => $qb->expr()->literal('shareOwner'),
1458
-				'item_type' => $qb->expr()->literal('file'),
1459
-				'file_source' => $qb->expr()->literal(42),
1460
-				'file_target' => $qb->expr()->literal('myTarget'),
1461
-				'permissions' => $qb->expr()->literal(13),
1462
-			]);
1463
-		$this->assertEquals(1, $qb->executeStatement());
1464
-		$id1 = $qb->getLastInsertId();
1465
-
1466
-		$qb = $this->dbConn->getQueryBuilder();
1467
-		$qb->insert('share')
1468
-			->values([
1469
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1470
-				'share_with' => $qb->expr()->literal('sharedWith'),
1471
-				'uid_owner' => $qb->expr()->literal('shareOwner'),
1472
-				'uid_initiator' => $qb->expr()->literal('sharedBy'),
1473
-				'item_type' => $qb->expr()->literal('file'),
1474
-				'file_source' => $qb->expr()->literal(42),
1475
-				'file_target' => $qb->expr()->literal('userTarget'),
1476
-				'permissions' => $qb->expr()->literal(0),
1477
-			]);
1478
-		$this->assertEquals(1, $qb->executeStatement());
1479
-		$id2 = $qb->getLastInsertId();
1480
-
1481
-		$file = $this->createMock(File::class);
1482
-		$file->method('getId')->willReturn(42);
1483
-		$this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1484
-		$this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
1485
-
1486
-		$shares = $this->provider->getSharesBy('shareOwner', IShare::TYPE_USER, null, true, -1, 0);
1487
-		$this->assertCount(2, $shares);
1488
-
1489
-		/** @var IShare $share */
1490
-		$share = $shares[0];
1491
-		$this->assertEquals($id1, $share->getId());
1492
-		$this->assertSame('sharedWith', $share->getSharedWith());
1493
-		$this->assertSame('shareOwner', $share->getShareOwner());
1494
-		$this->assertSame('shareOwner', $share->getSharedBy());
1495
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1496
-		$this->assertEquals(13, $share->getPermissions());
1497
-		$this->assertEquals('myTarget', $share->getTarget());
1498
-
1499
-		$share = $shares[1];
1500
-		$this->assertEquals($id2, $share->getId());
1501
-		$this->assertSame('sharedWith', $share->getSharedWith());
1502
-		$this->assertSame('shareOwner', $share->getShareOwner());
1503
-		$this->assertSame('sharedBy', $share->getSharedBy());
1504
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1505
-		$this->assertEquals(0, $share->getPermissions());
1506
-		$this->assertEquals('userTarget', $share->getTarget());
1507
-	}
1508
-
1509
-	public function testDeleteFromSelfGroupNoCustomShare(): void {
1510
-		$qb = $this->dbConn->getQueryBuilder();
1511
-		$stmt = $qb->insert('share')
1512
-			->values([
1513
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1514
-				'share_with' => $qb->expr()->literal('group'),
1515
-				'uid_owner' => $qb->expr()->literal('user1'),
1516
-				'uid_initiator' => $qb->expr()->literal('user1'),
1517
-				'item_type' => $qb->expr()->literal('file'),
1518
-				'file_source' => $qb->expr()->literal(1),
1519
-				'file_target' => $qb->expr()->literal('myTarget1'),
1520
-				'permissions' => $qb->expr()->literal(2)
1521
-			])->executeStatement();
1522
-		$this->assertEquals(1, $stmt);
1523
-		$id = $qb->getLastInsertId();
1524
-
1525
-		$user1 = $this->createMock(IUser::class);
1526
-		$user1->method('getUID')->willReturn('user1');
1527
-		$user2 = $this->createMock(IUser::class);
1528
-		$user2->method('getUID')->willReturn('user2');
1529
-		$this->userManager->method('get')->willReturnMap([
1530
-			['user1', $user1],
1531
-			['user2', $user2],
1532
-		]);
1533
-
1534
-		$group = $this->createMock(IGroup::class);
1535
-		$group->method('getGID')->willReturn('group');
1536
-		$group->method('inGroup')->with($user2)->willReturn(true);
1537
-		$group->method('getDisplayName')->willReturn('group-displayname');
1538
-		$this->groupManager->method('get')->with('group')->willReturn($group);
1539
-
1540
-		$file = $this->createMock(File::class);
1541
-		$file->method('getId')->willReturn(1);
1542
-
1543
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1544
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1545
-
1546
-		$share = $this->provider->getShareById($id);
1547
-
1548
-		$this->provider->deleteFromSelf($share, 'user2');
1549
-
1550
-		$qb = $this->dbConn->getQueryBuilder();
1551
-		$stmt = $qb->select('*')
1552
-			->from('share')
1553
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2)))
1554
-			->executeQuery();
1555
-
1556
-		$shares = $stmt->fetchAll();
1557
-		$stmt->closeCursor();
1558
-
1559
-		$this->assertCount(1, $shares);
1560
-		$share2 = $shares[0];
1561
-		$this->assertEquals($id, $share2['parent']);
1562
-		$this->assertEquals(0, $share2['permissions']);
1563
-		$this->assertEquals('user2', $share2['share_with']);
1564
-	}
1565
-
1566
-	public function testDeleteFromSelfGroupAlreadyCustomShare(): void {
1567
-		$qb = $this->dbConn->getQueryBuilder();
1568
-		$stmt = $qb->insert('share')
1569
-			->values([
1570
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1571
-				'share_with' => $qb->expr()->literal('group'),
1572
-				'uid_owner' => $qb->expr()->literal('user1'),
1573
-				'uid_initiator' => $qb->expr()->literal('user1'),
1574
-				'item_type' => $qb->expr()->literal('file'),
1575
-				'file_source' => $qb->expr()->literal(1),
1576
-				'file_target' => $qb->expr()->literal('myTarget1'),
1577
-				'permissions' => $qb->expr()->literal(2)
1578
-			])->executeStatement();
1579
-		$this->assertEquals(1, $stmt);
1580
-		$id = $qb->getLastInsertId();
1581
-
1582
-		$qb = $this->dbConn->getQueryBuilder();
1583
-		$stmt = $qb->insert('share')
1584
-			->values([
1585
-				'share_type' => $qb->expr()->literal(2),
1586
-				'share_with' => $qb->expr()->literal('user2'),
1587
-				'uid_owner' => $qb->expr()->literal('user1'),
1588
-				'uid_initiator' => $qb->expr()->literal('user1'),
1589
-				'item_type' => $qb->expr()->literal('file'),
1590
-				'file_source' => $qb->expr()->literal(1),
1591
-				'file_target' => $qb->expr()->literal('myTarget1'),
1592
-				'permissions' => $qb->expr()->literal(2),
1593
-				'parent' => $qb->expr()->literal($id),
1594
-			])->executeStatement();
1595
-		$this->assertEquals(1, $stmt);
1596
-
1597
-		$user1 = $this->createMock(IUser::class);
1598
-		$user1->method('getUID')->willReturn('user1');
1599
-		$user2 = $this->createMock(IUser::class);
1600
-		$user2->method('getUID')->willReturn('user2');
1601
-		$this->userManager->method('get')->willReturnMap([
1602
-			['user1', $user1],
1603
-			['user2', $user2],
1604
-		]);
1605
-
1606
-		$group = $this->createMock(IGroup::class);
1607
-		$group->method('getGID')->willReturn('group');
1608
-		$group->method('inGroup')->with($user2)->willReturn(true);
1609
-		$group->method('getDisplayName')->willReturn('group-displayname');
1610
-		$this->groupManager->method('get')->with('group')->willReturn($group);
1611
-
1612
-		$file = $this->createMock(File::class);
1613
-		$file->method('getId')->willReturn(1);
1614
-
1615
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1616
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1617
-
1618
-		$share = $this->provider->getShareById($id);
1619
-
1620
-		$this->provider->deleteFromSelf($share, 'user2');
1621
-
1622
-		$qb = $this->dbConn->getQueryBuilder();
1623
-		$stmt = $qb->select('*')
1624
-			->from('share')
1625
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2)))
1626
-			->executeQuery();
1627
-
1628
-		$shares = $stmt->fetchAll();
1629
-		$stmt->closeCursor();
1630
-
1631
-		$this->assertCount(1, $shares);
1632
-		$share2 = $shares[0];
1633
-		$this->assertEquals($id, $share2['parent']);
1634
-		$this->assertEquals(0, $share2['permissions']);
1635
-		$this->assertEquals('user2', $share2['share_with']);
1636
-	}
1637
-
1638
-
1639
-	public function testDeleteFromSelfGroupUserNotInGroup(): void {
1640
-		$qb = $this->dbConn->getQueryBuilder();
1641
-		$stmt = $qb->insert('share')
1642
-			->values([
1643
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1644
-				'share_with' => $qb->expr()->literal('group'),
1645
-				'uid_owner' => $qb->expr()->literal('user1'),
1646
-				'uid_initiator' => $qb->expr()->literal('user1'),
1647
-				'item_type' => $qb->expr()->literal('file'),
1648
-				'file_source' => $qb->expr()->literal(1),
1649
-				'file_target' => $qb->expr()->literal('myTarget1'),
1650
-				'permissions' => $qb->expr()->literal(2)
1651
-			])->executeStatement();
1652
-		$this->assertEquals(1, $stmt);
1653
-		$id = $qb->getLastInsertId();
1654
-
1655
-		$user1 = $this->createMock(IUser::class);
1656
-		$user1->method('getUID')->willReturn('user1');
1657
-		$user2 = $this->createMock(IUser::class);
1658
-		$user2->method('getUID')->willReturn('user2');
1659
-		$this->userManager->method('get')->willReturnMap([
1660
-			['user1', $user1],
1661
-			['user2', $user2],
1662
-		]);
1663
-
1664
-		$group = $this->createMock(IGroup::class);
1665
-		$group->method('getGID')->willReturn('group');
1666
-		$group->method('inGroup')->with($user2)->willReturn(false);
1667
-		$group->method('getDisplayName')->willReturn('group-displayname');
1668
-		$this->groupManager->method('get')->with('group')->willReturn($group);
1669
-
1670
-		$file = $this->createMock(File::class);
1671
-		$file->method('getId')->willReturn(1);
1672
-
1673
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1674
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1675
-
1676
-		$share = $this->provider->getShareById($id);
1677
-
1678
-		$this->provider->deleteFromSelf($share, 'user2');
1679
-	}
1680
-
1681
-
1682
-	public function testDeleteFromSelfGroupDoesNotExist(): void {
1683
-		$this->expectException(ProviderException::class);
1684
-		$this->expectExceptionMessage('Group "group" does not exist');
1685
-
1686
-		$qb = $this->dbConn->getQueryBuilder();
1687
-		$stmt = $qb->insert('share')
1688
-			->values([
1689
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1690
-				'share_with' => $qb->expr()->literal('group'),
1691
-				'uid_owner' => $qb->expr()->literal('user1'),
1692
-				'uid_initiator' => $qb->expr()->literal('user1'),
1693
-				'item_type' => $qb->expr()->literal('file'),
1694
-				'file_source' => $qb->expr()->literal(1),
1695
-				'file_target' => $qb->expr()->literal('myTarget1'),
1696
-				'permissions' => $qb->expr()->literal(2)
1697
-			])->executeStatement();
1698
-		$this->assertEquals(1, $stmt);
1699
-		$id = $qb->getLastInsertId();
1700
-
1701
-		$user1 = $this->createMock(IUser::class);
1702
-		$user1->method('getUID')->willReturn('user1');
1703
-		$user2 = $this->createMock(IUser::class);
1704
-		$user2->method('getUID')->willReturn('user2');
1705
-		$this->userManager->method('get')->willReturnMap([
1706
-			['user1', $user1],
1707
-			['user2', $user2],
1708
-		]);
1709
-
1710
-		$this->groupManager->method('get')->with('group')->willReturn(null);
1711
-
1712
-		$file = $this->createMock(File::class);
1713
-		$file->method('getId')->willReturn(1);
1714
-
1715
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1716
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1717
-
1718
-		$share = $this->provider->getShareById($id);
1719
-
1720
-		$this->provider->deleteFromSelf($share, 'user2');
1721
-	}
1722
-
1723
-	public function testDeleteFromSelfUser(): void {
1724
-		$qb = $this->dbConn->getQueryBuilder();
1725
-		$stmt = $qb->insert('share')
1726
-			->values([
1727
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1728
-				'share_with' => $qb->expr()->literal('user2'),
1729
-				'uid_owner' => $qb->expr()->literal('user1'),
1730
-				'uid_initiator' => $qb->expr()->literal('user1'),
1731
-				'item_type' => $qb->expr()->literal('file'),
1732
-				'file_source' => $qb->expr()->literal(1),
1733
-				'file_target' => $qb->expr()->literal('myTarget1'),
1734
-				'permissions' => $qb->expr()->literal(2)
1735
-			])->executeStatement();
1736
-		$this->assertEquals(1, $stmt);
1737
-		$id = $qb->getLastInsertId();
1738
-
1739
-		$user1 = $this->createMock(IUser::class);
1740
-		$user1->method('getUID')->willReturn('user1');
1741
-		$user1->method('getDisplayName')->willReturn('user1');
1742
-		$user2 = $this->createMock(IUser::class);
1743
-		$user2->method('getUID')->willReturn('user2');
1744
-		$user2->method('getDisplayName')->willReturn('user2');
1745
-		$this->userManager->method('get')->willReturnMap([
1746
-			['user1', $user1],
1747
-			['user2', $user2],
1748
-		]);
1749
-
1750
-		$file = $this->createMock(File::class);
1751
-		$file->method('getId')->willReturn(1);
1752
-
1753
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1754
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1755
-
1756
-		$share = $this->provider->getShareById($id);
1757
-
1758
-		$this->provider->deleteFromSelf($share, 'user2');
1759
-
1760
-		$qb = $this->dbConn->getQueryBuilder();
1761
-		$stmt = $qb->select('*')
1762
-			->from('share')
1763
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
1764
-			->executeQuery();
1765
-
1766
-		$shares = $stmt->fetchAll();
1767
-		$stmt->closeCursor();
1768
-
1769
-		$this->assertCount(0, $shares);
1770
-	}
1771
-
1772
-
1773
-	public function testDeleteFromSelfUserNotRecipient(): void {
1774
-		$this->expectException(ProviderException::class);
1775
-		$this->expectExceptionMessage('Recipient does not match');
1776
-
1777
-		$qb = $this->dbConn->getQueryBuilder();
1778
-		$stmt = $qb->insert('share')
1779
-			->values([
1780
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1781
-				'share_with' => $qb->expr()->literal('user2'),
1782
-				'uid_owner' => $qb->expr()->literal('user1'),
1783
-				'uid_initiator' => $qb->expr()->literal('user1'),
1784
-				'item_type' => $qb->expr()->literal('file'),
1785
-				'file_source' => $qb->expr()->literal(1),
1786
-				'file_target' => $qb->expr()->literal('myTarget1'),
1787
-				'permissions' => $qb->expr()->literal(2)
1788
-			])->executeStatement();
1789
-		$this->assertEquals(1, $stmt);
1790
-		$id = $qb->getLastInsertId();
1791
-
1792
-		$user1 = $this->createMock(IUser::class);
1793
-		$user1->method('getUID')->willReturn('user1');
1794
-		$user1->method('getDisplayName')->willReturn('user1');
1795
-		$user2 = $this->createMock(IUser::class);
1796
-		$user2->method('getUID')->willReturn('user2');
1797
-		$user2->method('getDisplayName')->willReturn('user2');
1798
-		$user3 = $this->createMock(IUser::class);
1799
-		$this->userManager->method('get')->willReturnMap([
1800
-			['user1', $user1],
1801
-			['user2', $user2],
1802
-		]);
1803
-
1804
-		$file = $this->createMock(File::class);
1805
-		$file->method('getId')->willReturn(1);
1806
-
1807
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1808
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1809
-
1810
-		$share = $this->provider->getShareById($id);
1811
-
1812
-		$this->provider->deleteFromSelf($share, $user3);
1813
-	}
1814
-
1815
-
1816
-	public function testDeleteFromSelfLink(): void {
1817
-		$this->expectException(ProviderException::class);
1818
-		$this->expectExceptionMessage('Invalid shareType');
1819
-
1820
-		$qb = $this->dbConn->getQueryBuilder();
1821
-		$stmt = $qb->insert('share')
1822
-			->values([
1823
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
1824
-				'uid_owner' => $qb->expr()->literal('user1'),
1825
-				'uid_initiator' => $qb->expr()->literal('user1'),
1826
-				'item_type' => $qb->expr()->literal('file'),
1827
-				'file_source' => $qb->expr()->literal(1),
1828
-				'file_target' => $qb->expr()->literal('myTarget1'),
1829
-				'permissions' => $qb->expr()->literal(2),
1830
-				'token' => $qb->expr()->literal('token'),
1831
-			])->executeStatement();
1832
-		$this->assertEquals(1, $stmt);
1833
-		$id = $qb->getLastInsertId();
1834
-
1835
-		$user1 = $this->createMock(IUser::class);
1836
-		$user1->method('getUID')->willReturn('user1');
1837
-		$this->userManager->method('get')->willReturnMap([
1838
-			['user1', $user1],
1839
-		]);
1840
-
1841
-		$file = $this->createMock(File::class);
1842
-		$file->method('getId')->willReturn(1);
1843
-
1844
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1845
-		$this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1846
-
1847
-		$share = $this->provider->getShareById($id);
1848
-
1849
-		$this->provider->deleteFromSelf($share, $user1);
1850
-	}
1851
-
1852
-	public function testUpdateUser(): void {
1853
-		$id = $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user2',
1854
-			'file', 42, 'target', 31, null, null);
1855
-
1856
-		$users = [];
1857
-		for ($i = 0; $i < 6; $i++) {
1858
-			$user = $this->createMock(IUser::class);
1859
-			$user->method('getUID')->willReturn('user' . $i);
1860
-			$user->method('getDisplayName')->willReturn('user' . $i);
1861
-			$users['user' . $i] = $user;
1862
-		}
1863
-
1864
-		$this->userManager->method('get')->willReturnCallback(
1865
-			function ($userId) use ($users) {
1866
-				return $users[$userId];
1867
-			}
1868
-		);
1869
-
1870
-		$file1 = $this->createMock(File::class);
1871
-		$file1->method('getId')->willReturn(42);
1872
-		$file2 = $this->createMock(File::class);
1873
-		$file2->method('getId')->willReturn(43);
1874
-
1875
-		$folder1 = $this->createMock(Folder::class);
1876
-		$folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
1877
-		$folder2 = $this->createMock(Folder::class);
1878
-		$folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
1879
-
1880
-		$this->rootFolder->method('getUserFolder')->willReturnMap([
1881
-			['user2', $folder1],
1882
-			['user5', $folder2],
1883
-		]);
1884
-
1885
-		$share = $this->provider->getShareById($id);
1886
-
1887
-		$share->setSharedWith('user3');
1888
-		$share->setSharedBy('user4');
1889
-		$share->setShareOwner('user5');
1890
-		$share->setNode($file2);
1891
-		$share->setPermissions(1);
1892
-
1893
-		$share2 = $this->provider->update($share);
1894
-
1895
-		$this->assertEquals($id, $share2->getId());
1896
-		$this->assertSame('user3', $share2->getSharedWith());
1897
-		$this->assertSame('user4', $share2->getSharedBy());
1898
-		$this->assertSame('user5', $share2->getShareOwner());
1899
-		$this->assertSame(1, $share2->getPermissions());
1900
-
1901
-		$share2 = $this->provider->getShareById($id);
1902
-
1903
-		$this->assertEquals($id, $share2->getId());
1904
-		$this->assertSame('user3', $share2->getSharedWith());
1905
-		$this->assertSame('user4', $share2->getSharedBy());
1906
-		$this->assertSame('user5', $share2->getShareOwner());
1907
-		$this->assertSame(1, $share2->getPermissions());
1908
-	}
1909
-
1910
-	public function testUpdateLink(): void {
1911
-		$id = $this->addShareToDB(IShare::TYPE_LINK, null, 'user1', 'user2',
1912
-			'file', 42, 'target', 31, null, null);
1913
-
1914
-		$users = [];
1915
-		for ($i = 0; $i < 6; $i++) {
1916
-			$user = $this->createMock(IUser::class);
1917
-			$user->method('getUID')->willReturn('user' . $i);
1918
-			$users['user' . $i] = $user;
1919
-		}
1920
-
1921
-		$this->userManager->method('get')->willReturnCallback(
1922
-			function ($userId) use ($users) {
1923
-				return $users[$userId];
1924
-			}
1925
-		);
1926
-
1927
-		$file1 = $this->createMock(File::class);
1928
-		$file1->method('getId')->willReturn(42);
1929
-		$file2 = $this->createMock(File::class);
1930
-		$file2->method('getId')->willReturn(43);
1931
-
1932
-		$folder1 = $this->createMock(Folder::class);
1933
-		$folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
1934
-		$folder2 = $this->createMock(Folder::class);
1935
-		$folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
1936
-
1937
-		$this->rootFolder->method('getUserFolder')->willReturnMap([
1938
-			['user2', $folder1],
1939
-			['user5', $folder2],
1940
-		]);
1941
-
1942
-		$share = $this->provider->getShareById($id);
1943
-
1944
-		$share->setPassword('password');
1945
-		$share->setSendPasswordByTalk(true);
1946
-		$share->setSharedBy('user4');
1947
-		$share->setShareOwner('user5');
1948
-		$share->setNode($file2);
1949
-		$share->setPermissions(1);
1950
-
1951
-		$share2 = $this->provider->update($share);
1952
-
1953
-		$this->assertEquals($id, $share2->getId());
1954
-		$this->assertEquals('password', $share2->getPassword());
1955
-		$this->assertSame(true, $share2->getSendPasswordByTalk());
1956
-		$this->assertSame('user4', $share2->getSharedBy());
1957
-		$this->assertSame('user5', $share2->getShareOwner());
1958
-		$this->assertSame(1, $share2->getPermissions());
1959
-
1960
-		$share2 = $this->provider->getShareById($id);
1961
-
1962
-		$this->assertEquals($id, $share2->getId());
1963
-		$this->assertEquals('password', $share2->getPassword());
1964
-		$this->assertSame(true, $share2->getSendPasswordByTalk());
1965
-		$this->assertSame('user4', $share2->getSharedBy());
1966
-		$this->assertSame('user5', $share2->getShareOwner());
1967
-		$this->assertSame(1, $share2->getPermissions());
1968
-	}
1969
-
1970
-	public function testUpdateLinkRemovePassword(): void {
1971
-		$id = $this->addShareToDB(IShare::TYPE_LINK, 'foo', 'user1', 'user2',
1972
-			'file', 42, 'target', 31, null, null);
1973
-
1974
-		$qb = $this->dbConn->getQueryBuilder();
1975
-		$qb->update('share');
1976
-		$qb->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1977
-		$qb->set('password', $qb->createNamedParameter('password'));
1978
-		$this->assertEquals(1, $qb->executeStatement());
1979
-
1980
-		$users = [];
1981
-		for ($i = 0; $i < 6; $i++) {
1982
-			$user = $this->createMock(IUser::class);
1983
-			$user->method('getUID')->willReturn('user' . $i);
1984
-			$users['user' . $i] = $user;
1985
-		}
1986
-
1987
-		$this->userManager->method('get')->willReturnCallback(
1988
-			function ($userId) use ($users) {
1989
-				return $users[$userId];
1990
-			}
1991
-		);
1992
-
1993
-		$file1 = $this->createMock(File::class);
1994
-		$file1->method('getId')->willReturn(42);
1995
-		$file2 = $this->createMock(File::class);
1996
-		$file2->method('getId')->willReturn(43);
1997
-
1998
-		$folder1 = $this->createMock(Folder::class);
1999
-		$folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
2000
-		$folder2 = $this->createMock(Folder::class);
2001
-		$folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
2002
-
2003
-		$this->rootFolder->method('getUserFolder')->willReturnMap([
2004
-			['user2', $folder1],
2005
-			['user5', $folder2],
2006
-		]);
2007
-
2008
-		$share = $this->provider->getShareById($id);
2009
-
2010
-		$share->setPassword(null);
2011
-		$share->setSharedBy('user4');
2012
-		$share->setShareOwner('user5');
2013
-		$share->setNode($file2);
2014
-		$share->setPermissions(1);
2015
-
2016
-		$share2 = $this->provider->update($share);
2017
-
2018
-		$this->assertEquals($id, $share2->getId());
2019
-		$this->assertEquals(null, $share2->getPassword());
2020
-		$this->assertSame('user4', $share2->getSharedBy());
2021
-		$this->assertSame('user5', $share2->getShareOwner());
2022
-		$this->assertSame(1, $share2->getPermissions());
2023
-
2024
-		$share2 = $this->provider->getShareById($id);
2025
-
2026
-		$this->assertEquals($id, $share2->getId());
2027
-		$this->assertEquals(null, $share2->getPassword());
2028
-		$this->assertSame('user4', $share2->getSharedBy());
2029
-		$this->assertSame('user5', $share2->getShareOwner());
2030
-		$this->assertSame(1, $share2->getPermissions());
2031
-	}
2032
-
2033
-	public function testUpdateGroupNoSub(): void {
2034
-		$id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user2',
2035
-			'file', 42, 'target', 31, null, null);
2036
-
2037
-		$users = [];
2038
-		for ($i = 0; $i < 6; $i++) {
2039
-			$user = $this->createMock(IUser::class);
2040
-			$user->method('getUID')->willReturn('user' . $i);
2041
-			$users['user' . $i] = $user;
2042
-		}
2043
-
2044
-		$this->userManager->method('get')->willReturnCallback(
2045
-			function ($userId) use ($users) {
2046
-				return $users[$userId];
2047
-			}
2048
-		);
2049
-
2050
-		$groups = [];
2051
-		for ($i = 0; $i < 2; $i++) {
2052
-			$group = $this->createMock(IGroup::class);
2053
-			$group->method('getGID')->willReturn('group' . $i);
2054
-			$group->method('getDisplayName')->willReturn('group-displayname' . $i);
2055
-			$groups['group' . $i] = $group;
2056
-		}
2057
-
2058
-		$this->groupManager->method('get')->willReturnCallback(
2059
-			function ($groupId) use ($groups) {
2060
-				return $groups[$groupId];
2061
-			}
2062
-		);
2063
-
2064
-		$file1 = $this->createMock(File::class);
2065
-		$file1->method('getId')->willReturn(42);
2066
-		$file2 = $this->createMock(File::class);
2067
-		$file2->method('getId')->willReturn(43);
2068
-
2069
-		$folder1 = $this->createMock(Folder::class);
2070
-		$folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
2071
-		$folder2 = $this->createMock(Folder::class);
2072
-		$folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
2073
-
2074
-		$this->rootFolder->method('getUserFolder')->willReturnMap([
2075
-			['user2', $folder1],
2076
-			['user5', $folder2],
2077
-		]);
2078
-
2079
-		$share = $this->provider->getShareById($id);
2080
-
2081
-		$share->setSharedWith('group0');
2082
-		$share->setSharedBy('user4');
2083
-		$share->setShareOwner('user5');
2084
-		$share->setNode($file2);
2085
-		$share->setPermissions(1);
2086
-
2087
-		$share2 = $this->provider->update($share);
2088
-
2089
-		$this->assertEquals($id, $share2->getId());
2090
-		// Group shares do not allow updating the recipient
2091
-		$this->assertSame('group0', $share2->getSharedWith());
2092
-		$this->assertSame('user4', $share2->getSharedBy());
2093
-		$this->assertSame('user5', $share2->getShareOwner());
2094
-		$this->assertSame(1, $share2->getPermissions());
2095
-
2096
-		$share2 = $this->provider->getShareById($id);
2097
-
2098
-		$this->assertEquals($id, $share2->getId());
2099
-		// Group shares do not allow updating the recipient
2100
-		$this->assertSame('group0', $share2->getSharedWith());
2101
-		$this->assertSame('user4', $share2->getSharedBy());
2102
-		$this->assertSame('user5', $share2->getShareOwner());
2103
-		$this->assertSame(1, $share2->getPermissions());
2104
-	}
2105
-
2106
-	public function testUpdateGroupSubShares(): void {
2107
-		$id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user2',
2108
-			'file', 42, 'target', 31, null, null);
2109
-
2110
-		$id2 = $this->addShareToDB(2, 'user0', 'user1', 'user2',
2111
-			'file', 42, 'mytarget', 31, null, null, $id);
2112
-
2113
-		$id3 = $this->addShareToDB(2, 'user3', 'user1', 'user2',
2114
-			'file', 42, 'mytarget2', 0, null, null, $id);
2115
-
2116
-		$users = [];
2117
-		for ($i = 0; $i < 6; $i++) {
2118
-			$user = $this->createMock(IUser::class);
2119
-			$user->method('getUID')->willReturn('user' . $i);
2120
-			$users['user' . $i] = $user;
2121
-		}
2122
-
2123
-		$this->userManager->method('get')->willReturnCallback(
2124
-			function ($userId) use ($users) {
2125
-				return $users[$userId];
2126
-			}
2127
-		);
2128
-
2129
-		$groups = [];
2130
-		for ($i = 0; $i < 2; $i++) {
2131
-			$group = $this->createMock(IGroup::class);
2132
-			$group->method('getGID')->willReturn('group' . $i);
2133
-			$group->method('getDisplayName')->willReturn('group-displayname' . $i);
2134
-			$groups['group' . $i] = $group;
2135
-		}
2136
-
2137
-		$this->groupManager->method('get')->willReturnCallback(
2138
-			function ($groupId) use ($groups) {
2139
-				return $groups[$groupId];
2140
-			}
2141
-		);
2142
-
2143
-		$file1 = $this->createMock(File::class);
2144
-		$file1->method('getId')->willReturn(42);
2145
-		$file2 = $this->createMock(File::class);
2146
-		$file2->method('getId')->willReturn(43);
2147
-
2148
-		$folder1 = $this->createMock(Folder::class);
2149
-		$folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
2150
-		$folder2 = $this->createMock(Folder::class);
2151
-		$folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
2152
-
2153
-		$this->rootFolder->method('getUserFolder')->willReturnMap([
2154
-			['user2', $folder1],
2155
-			['user5', $folder2],
2156
-		]);
2157
-
2158
-		$share = $this->provider->getShareById($id);
2159
-
2160
-		$share->setSharedWith('group0');
2161
-		$share->setSharedBy('user4');
2162
-		$share->setShareOwner('user5');
2163
-		$share->setNode($file2);
2164
-		$share->setPermissions(1);
2165
-
2166
-		$share2 = $this->provider->update($share);
2167
-
2168
-		$this->assertEquals($id, $share2->getId());
2169
-		// Group shares do not allow updating the recipient
2170
-		$this->assertSame('group0', $share2->getSharedWith());
2171
-		$this->assertSame('user4', $share2->getSharedBy());
2172
-		$this->assertSame('user5', $share2->getShareOwner());
2173
-		$this->assertSame(1, $share2->getPermissions());
2174
-
2175
-		$share2 = $this->provider->getShareById($id);
2176
-
2177
-		$this->assertEquals($id, $share2->getId());
2178
-		// Group shares do not allow updating the recipient
2179
-		$this->assertSame('group0', $share2->getSharedWith());
2180
-		$this->assertSame('user4', $share2->getSharedBy());
2181
-		$this->assertSame('user5', $share2->getShareOwner());
2182
-		$this->assertSame(1, $share2->getPermissions());
2183
-
2184
-		$qb = $this->dbConn->getQueryBuilder();
2185
-		$stmt = $qb->select('*')
2186
-			->from('share')
2187
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($id)))
2188
-			->orderBy('id')
2189
-			->executeQuery();
2190
-
2191
-		$shares = $stmt->fetchAll();
2192
-
2193
-		$this->assertSame('user0', $shares[0]['share_with']);
2194
-		$this->assertSame('user4', $shares[0]['uid_initiator']);
2195
-		$this->assertSame('user5', $shares[0]['uid_owner']);
2196
-		$this->assertSame(1, (int)$shares[0]['permissions']);
2197
-
2198
-		$this->assertSame('user3', $shares[1]['share_with']);
2199
-		$this->assertSame('user4', $shares[1]['uid_initiator']);
2200
-		$this->assertSame('user5', $shares[1]['uid_owner']);
2201
-		$this->assertSame(0, (int)$shares[1]['permissions']);
2202
-
2203
-
2204
-		$stmt->closeCursor();
2205
-	}
2206
-
2207
-	public function testMoveUserShare(): void {
2208
-		$id = $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user1', 'file',
2209
-			42, 'mytaret', 31, null, null);
2210
-
2211
-		$user0 = $this->createMock(IUser::class);
2212
-		$user0->method('getUID')->willReturn('user0');
2213
-		$user0->method('getDisplayName')->willReturn('user0');
2214
-		$user1 = $this->createMock(IUser::class);
2215
-		$user1->method('getUID')->willReturn('user1');
2216
-		$user1->method('getDisplayName')->willReturn('user1');
2217
-
2218
-		$this->userManager->method('get')->willReturnMap([
2219
-			['user0', $user0],
2220
-			['user1', $user1],
2221
-		]);
2222
-
2223
-		$file = $this->createMock(File::class);
2224
-		$file->method('getId')->willReturn(42);
2225
-
2226
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
2227
-		$this->rootFolder->method('getFirstNodeById')->willReturn($file);
2228
-
2229
-		$share = $this->provider->getShareById($id, null);
2230
-
2231
-		$share->setTarget('/newTarget');
2232
-		$this->provider->move($share, $user0);
2233
-
2234
-		$share = $this->provider->getShareById($id, null);
2235
-		$this->assertSame('/newTarget', $share->getTarget());
2236
-	}
2237
-
2238
-	public function testMoveGroupShare(): void {
2239
-		$id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user1', 'file',
2240
-			42, 'mytaret', 31, null, null);
2241
-
2242
-		$user0 = $this->createMock(IUser::class);
2243
-		$user0->method('getUID')->willReturn('user0');
2244
-		$user1 = $this->createMock(IUser::class);
2245
-		$user1->method('getUID')->willReturn('user1');
2246
-
2247
-		$group0 = $this->createMock(IGroup::class);
2248
-		$group0->method('getGID')->willReturn('group0');
2249
-		$group0->method('inGroup')->with($user0)->willReturn(true);
2250
-		$group0->method('getDisplayName')->willReturn('group0-displayname');
2251
-
2252
-		$this->groupManager->method('get')->with('group0')->willReturn($group0);
2253
-
2254
-		$this->userManager->method('get')->willReturnMap([
2255
-			['user0', $user0],
2256
-			['user1', $user1],
2257
-		]);
2258
-
2259
-		$folder = $this->createMock(Folder::class);
2260
-		$folder->method('getId')->willReturn(42);
2261
-
2262
-		$this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
2263
-		$this->rootFolder->method('getFirstNodeById')->willReturn($folder);
2264
-
2265
-		$share = $this->provider->getShareById($id, 'user0');
2266
-
2267
-		$share->setTarget('/newTarget');
2268
-		$this->provider->move($share, 'user0');
2269
-
2270
-		$share = $this->provider->getShareById($id, 'user0');
2271
-		$this->assertSame('/newTarget', $share->getTarget());
2272
-
2273
-		$share->setTarget('/ultraNewTarget');
2274
-		$this->provider->move($share, 'user0');
2275
-
2276
-		$share = $this->provider->getShareById($id, 'user0');
2277
-		$this->assertSame('/ultraNewTarget', $share->getTarget());
2278
-	}
2279
-
2280
-	public static function dataDeleteUser(): array {
2281
-		return [
2282
-			[IShare::TYPE_USER, 'a', 'b', 'c', 'a', true],
2283
-			[IShare::TYPE_USER, 'a', 'b', 'c', 'b', false],
2284
-			[IShare::TYPE_USER, 'a', 'b', 'c', 'c', true],
2285
-			[IShare::TYPE_USER, 'a', 'b', 'c', 'd', false],
2286
-			[IShare::TYPE_GROUP, 'a', 'b', 'c', 'a', true],
2287
-			[IShare::TYPE_GROUP, 'a', 'b', 'c', 'b', false],
2288
-			// The group c is still valid but user c is deleted so group share stays
2289
-			[IShare::TYPE_GROUP, 'a', 'b', 'c', 'c', false],
2290
-			[IShare::TYPE_GROUP, 'a', 'b', 'c', 'd', false],
2291
-			[IShare::TYPE_LINK, 'a', 'b', 'c', 'a', true],
2292
-			// To avoid invisible link shares delete initiated link shares as well (see #22327)
2293
-			[IShare::TYPE_LINK, 'a', 'b', 'c', 'b', true],
2294
-			[IShare::TYPE_LINK, 'a', 'b', 'c', 'c', false],
2295
-			[IShare::TYPE_LINK, 'a', 'b', 'c', 'd', false],
2296
-		];
2297
-	}
2298
-
2299
-	/**
2300
-	 *
2301
-	 * @param int $type The shareType (user/group/link)
2302
-	 * @param string $owner The owner of the share (uid)
2303
-	 * @param string $initiator The initiator of the share (uid)
2304
-	 * @param string $recipient The recipient of the share (uid/gid/pass)
2305
-	 * @param string $deletedUser The user that is deleted
2306
-	 * @param bool $rowDeleted Is the row deleted in this setup
2307
-	 */
2308
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataDeleteUser')]
2309
-	public function testDeleteUser($type, $owner, $initiator, $recipient, $deletedUser, $rowDeleted): void {
2310
-		$qb = $this->dbConn->getQueryBuilder();
2311
-		$qb->insert('share')
2312
-			->setValue('share_type', $qb->createNamedParameter($type))
2313
-			->setValue('uid_owner', $qb->createNamedParameter($owner))
2314
-			->setValue('uid_initiator', $qb->createNamedParameter($initiator))
2315
-			->setValue('share_with', $qb->createNamedParameter($recipient))
2316
-			->setValue('item_type', $qb->createNamedParameter('file'))
2317
-			->setValue('item_source', $qb->createNamedParameter(42))
2318
-			->setValue('file_source', $qb->createNamedParameter(42))
2319
-			->executeStatement();
2320
-
2321
-		$id = $qb->getLastInsertId();
2322
-
2323
-		$this->provider->userDeleted($deletedUser, $type);
2324
-
2325
-		$qb = $this->dbConn->getQueryBuilder();
2326
-		$qb->select('*')
2327
-			->from('share')
2328
-			->where(
2329
-				$qb->expr()->eq('id', $qb->createNamedParameter($id))
2330
-			);
2331
-		$cursor = $qb->executeQuery();
2332
-		$data = $cursor->fetchAll();
2333
-		$cursor->closeCursor();
2334
-
2335
-		$this->assertCount($rowDeleted ? 0 : 1, $data);
2336
-	}
2337
-
2338
-	public static function dataDeleteUserGroup(): array {
2339
-		return [
2340
-			['a', 'b', 'c', 'a', true, true],
2341
-			['a', 'b', 'c', 'b', false, false],
2342
-			['a', 'b', 'c', 'c', false, true],
2343
-			['a', 'b', 'c', 'd', false, false],
2344
-		];
2345
-	}
2346
-
2347
-	/**
2348
-	 *
2349
-	 * @param string $owner The owner of the share (uid)
2350
-	 * @param string $initiator The initiator of the share (uid)
2351
-	 * @param string $recipient The recipient of the usergroup share (uid)
2352
-	 * @param string $deletedUser The user that is deleted
2353
-	 * @param bool $groupShareDeleted
2354
-	 * @param bool $userGroupShareDeleted
2355
-	 */
2356
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataDeleteUserGroup')]
2357
-	public function testDeleteUserGroup($owner, $initiator, $recipient, $deletedUser, $groupShareDeleted, $userGroupShareDeleted): void {
2358
-		$qb = $this->dbConn->getQueryBuilder();
2359
-		$qb->insert('share')
2360
-			->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
2361
-			->setValue('uid_owner', $qb->createNamedParameter($owner))
2362
-			->setValue('uid_initiator', $qb->createNamedParameter($initiator))
2363
-			->setValue('share_with', $qb->createNamedParameter('group'))
2364
-			->setValue('item_type', $qb->createNamedParameter('file'))
2365
-			->setValue('item_source', $qb->createNamedParameter(42))
2366
-			->setValue('file_source', $qb->createNamedParameter(42))
2367
-			->executeStatement();
2368
-		$groupId = $qb->getLastInsertId();
2369
-
2370
-		$qb = $this->dbConn->getQueryBuilder();
2371
-		$qb->insert('share')
2372
-			->setValue('share_type', $qb->createNamedParameter(2))
2373
-			->setValue('uid_owner', $qb->createNamedParameter($owner))
2374
-			->setValue('uid_initiator', $qb->createNamedParameter($initiator))
2375
-			->setValue('share_with', $qb->createNamedParameter($recipient))
2376
-			->setValue('item_type', $qb->createNamedParameter('file'))
2377
-			->setValue('item_source', $qb->createNamedParameter(42))
2378
-			->setValue('file_source', $qb->createNamedParameter(42))
2379
-			->executeStatement();
2380
-		$userGroupId = $qb->getLastInsertId();
2381
-
2382
-		$this->provider->userDeleted($deletedUser, IShare::TYPE_GROUP);
2383
-
2384
-		$qb = $this->dbConn->getQueryBuilder();
2385
-		$qb->select('*')
2386
-			->from('share')
2387
-			->where(
2388
-				$qb->expr()->eq('id', $qb->createNamedParameter($userGroupId))
2389
-			);
2390
-		$cursor = $qb->executeQuery();
2391
-		$data = $cursor->fetchAll();
2392
-		$cursor->closeCursor();
2393
-		$this->assertCount($userGroupShareDeleted ? 0 : 1, $data);
2394
-
2395
-		$qb = $this->dbConn->getQueryBuilder();
2396
-		$qb->select('*')
2397
-			->from('share')
2398
-			->where(
2399
-				$qb->expr()->eq('id', $qb->createNamedParameter($groupId))
2400
-			);
2401
-		$cursor = $qb->executeQuery();
2402
-		$data = $cursor->fetchAll();
2403
-		$cursor->closeCursor();
2404
-		$this->assertCount($groupShareDeleted ? 0 : 1, $data);
2405
-	}
2406
-
2407
-	public static function dataGroupDeleted(): array {
2408
-		return [
2409
-			[
2410
-				[
2411
-					'type' => IShare::TYPE_USER,
2412
-					'recipient' => 'user',
2413
-					'children' => []
2414
-				], 'group', false
2415
-			],
2416
-			[
2417
-				[
2418
-					'type' => IShare::TYPE_USER,
2419
-					'recipient' => 'user',
2420
-					'children' => []
2421
-				], 'user', false
2422
-			],
2423
-			[
2424
-				[
2425
-					'type' => IShare::TYPE_LINK,
2426
-					'recipient' => 'user',
2427
-					'children' => []
2428
-				], 'group', false
2429
-			],
2430
-			[
2431
-				[
2432
-					'type' => IShare::TYPE_GROUP,
2433
-					'recipient' => 'group1',
2434
-					'children' => [
2435
-						'foo',
2436
-						'bar'
2437
-					]
2438
-				], 'group2', false
2439
-			],
2440
-			[
2441
-				[
2442
-					'type' => IShare::TYPE_GROUP,
2443
-					'recipient' => 'group1',
2444
-					'children' => [
2445
-						'foo',
2446
-						'bar'
2447
-					]
2448
-				], 'group1', true
2449
-			],
2450
-		];
2451
-	}
2452
-
2453
-	/**
2454
-	 *
2455
-	 * @param $shares
2456
-	 * @param $groupToDelete
2457
-	 * @param $shouldBeDeleted
2458
-	 */
2459
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataGroupDeleted')]
2460
-	public function testGroupDeleted($shares, $groupToDelete, $shouldBeDeleted): void {
2461
-		$qb = $this->dbConn->getQueryBuilder();
2462
-		$qb->insert('share')
2463
-			->setValue('share_type', $qb->createNamedParameter($shares['type']))
2464
-			->setValue('uid_owner', $qb->createNamedParameter('owner'))
2465
-			->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2466
-			->setValue('share_with', $qb->createNamedParameter($shares['recipient']))
2467
-			->setValue('item_type', $qb->createNamedParameter('file'))
2468
-			->setValue('item_source', $qb->createNamedParameter(42))
2469
-			->setValue('file_source', $qb->createNamedParameter(42))
2470
-			->executeStatement();
2471
-		$ids = [$qb->getLastInsertId()];
2472
-
2473
-		foreach ($shares['children'] as $child) {
2474
-			$qb = $this->dbConn->getQueryBuilder();
2475
-			$qb->insert('share')
2476
-				->setValue('share_type', $qb->createNamedParameter(2))
2477
-				->setValue('uid_owner', $qb->createNamedParameter('owner'))
2478
-				->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2479
-				->setValue('share_with', $qb->createNamedParameter($child))
2480
-				->setValue('item_type', $qb->createNamedParameter('file'))
2481
-				->setValue('item_source', $qb->createNamedParameter(42))
2482
-				->setValue('file_source', $qb->createNamedParameter(42))
2483
-				->setValue('parent', $qb->createNamedParameter($ids[0]))
2484
-				->executeStatement();
2485
-			$ids[] = $qb->getLastInsertId();
2486
-		}
2487
-
2488
-		$this->provider->groupDeleted($groupToDelete);
2489
-
2490
-		$qb = $this->dbConn->getQueryBuilder();
2491
-		$cursor = $qb->select('*')
2492
-			->from('share')
2493
-			->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
2494
-			->executeQuery();
2495
-		$data = $cursor->fetchAll();
2496
-		$cursor->closeCursor();
2497
-
2498
-		$this->assertCount($shouldBeDeleted ? 0 : count($ids), $data);
2499
-	}
2500
-
2501
-	public static function dataUserDeletedFromGroup(): array {
2502
-		return [
2503
-			['group1', 'user1', true],
2504
-			['group1', 'user2', false],
2505
-			['group2', 'user1', false],
2506
-		];
2507
-	}
2508
-
2509
-	/**
2510
-	 * Given a group share with 'group1'
2511
-	 * And a user specific group share with 'user1'.
2512
-	 * User $user is deleted from group $gid.
2513
-	 *
2514
-	 *
2515
-	 * @param string $group
2516
-	 * @param string $user
2517
-	 * @param bool $toDelete
2518
-	 */
2519
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataUserDeletedFromGroup')]
2520
-	public function testUserDeletedFromGroup($group, $user, $toDelete): void {
2521
-		$qb = $this->dbConn->getQueryBuilder();
2522
-		$qb->insert('share')
2523
-			->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
2524
-			->setValue('uid_owner', $qb->createNamedParameter('owner'))
2525
-			->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2526
-			->setValue('share_with', $qb->createNamedParameter('group1'))
2527
-			->setValue('item_type', $qb->createNamedParameter('file'))
2528
-			->setValue('item_source', $qb->createNamedParameter(42))
2529
-			->setValue('file_source', $qb->createNamedParameter(42));
2530
-		$qb->executeStatement();
2531
-		$id1 = $qb->getLastInsertId();
2532
-
2533
-		$qb = $this->dbConn->getQueryBuilder();
2534
-		$qb->insert('share')
2535
-			->setValue('share_type', $qb->createNamedParameter(2))
2536
-			->setValue('uid_owner', $qb->createNamedParameter('owner'))
2537
-			->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2538
-			->setValue('share_with', $qb->createNamedParameter('user1'))
2539
-			->setValue('item_type', $qb->createNamedParameter('file'))
2540
-			->setValue('item_source', $qb->createNamedParameter(42))
2541
-			->setValue('file_source', $qb->createNamedParameter(42))
2542
-			->setValue('parent', $qb->createNamedParameter($id1));
2543
-		$qb->executeStatement();
2544
-		$id2 = $qb->getLastInsertId();
2545
-
2546
-		$this->provider->userDeletedFromGroup($user, $group);
2547
-
2548
-		$qb = $this->dbConn->getQueryBuilder();
2549
-		$qb->select('*')
2550
-			->from('share')
2551
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id2)));
2552
-		$cursor = $qb->executeQuery();
2553
-		$data = $cursor->fetchAll();
2554
-		$cursor->closeCursor();
2555
-
2556
-		$this->assertCount($toDelete ? 0 : 1, $data);
2557
-	}
2558
-
2559
-	public function testGetSharesInFolder(): void {
2560
-		$userManager = Server::get(IUserManager::class);
2561
-		$groupManager = Server::get(IGroupManager::class);
2562
-		$rootFolder = Server::get(IRootFolder::class);
2563
-
2564
-		$provider = new DefaultShareProvider(
2565
-			$this->dbConn,
2566
-			$userManager,
2567
-			$groupManager,
2568
-			$rootFolder,
2569
-			$this->mailer,
2570
-			$this->defaults,
2571
-			$this->l10nFactory,
2572
-			$this->urlGenerator,
2573
-			$this->timeFactory,
2574
-			$this->logger,
2575
-			$this->shareManager,
2576
-			$this->config,
2577
-		);
2578
-
2579
-		$password = md5(time());
2580
-
2581
-		$u1 = $userManager->createUser('testShare1', $password);
2582
-		$u2 = $userManager->createUser('testShare2', $password);
2583
-		$u3 = $userManager->createUser('testShare3', $password);
2584
-
2585
-		$g1 = $groupManager->createGroup('group1');
2586
-
2587
-		$u1Folder = $rootFolder->getUserFolder($u1->getUID());
2588
-		$folder1 = $u1Folder->newFolder('foo');
2589
-		$file1 = $folder1->newFile('bar');
2590
-		$folder2 = $folder1->newFolder('baz');
2591
-
2592
-		$shareManager = Server::get(IShareManager::class);
2593
-		$share1 = $shareManager->newShare();
2594
-		$share1->setNode($folder1)
2595
-			->setSharedBy($u1->getUID())
2596
-			->setSharedWith($u2->getUID())
2597
-			->setShareOwner($u1->getUID())
2598
-			->setShareType(IShare::TYPE_USER)
2599
-			->setPermissions(Constants::PERMISSION_ALL);
2600
-		$share1 = $this->provider->create($share1);
2601
-
2602
-		$share2 = $shareManager->newShare();
2603
-		$share2->setNode($file1)
2604
-			->setSharedBy($u2->getUID())
2605
-			->setSharedWith($u3->getUID())
2606
-			->setShareOwner($u1->getUID())
2607
-			->setShareType(IShare::TYPE_USER)
2608
-			->setPermissions(Constants::PERMISSION_READ);
2609
-		$share2 = $this->provider->create($share2);
2610
-
2611
-		$share3 = $shareManager->newShare();
2612
-		$share3->setNode($folder2)
2613
-			->setSharedBy($u2->getUID())
2614
-			->setShareOwner($u1->getUID())
2615
-			->setShareType(IShare::TYPE_LINK)
2616
-			->setPermissions(Constants::PERMISSION_READ);
2617
-		$share3 = $this->provider->create($share3);
2618
-
2619
-		$share4 = $shareManager->newShare();
2620
-		$share4->setNode($folder2)
2621
-			->setSharedBy($u1->getUID())
2622
-			->setSharedWith($g1->getGID())
2623
-			->setShareOwner($u1->getUID())
2624
-			->setShareType(IShare::TYPE_GROUP)
2625
-			->setPermissions(Constants::PERMISSION_READ);
2626
-		$share4 = $this->provider->create($share4);
2627
-
2628
-		$result = $provider->getSharesInFolder($u1->getUID(), $folder1, false);
2629
-		$this->assertCount(1, $result);
2630
-		$shares = array_pop($result);
2631
-		$this->assertCount(1, $shares);
2632
-		$this->assertSame($folder2->getId(), $shares[0]->getNodeId());
2633
-
2634
-		$result = $provider->getSharesInFolder($u1->getUID(), $folder1, true);
2635
-		$this->assertCount(2, $result);
2636
-
2637
-		$file_shares = $result[$file1->getId()];
2638
-		$this->assertCount(1, $file_shares);
2639
-		$this->assertSame($file1->getId(), $file_shares[0]->getNodeId());
2640
-		$this->assertSame(IShare::TYPE_USER, $file_shares[0]->getShareType());
2641
-
2642
-		$folder_shares = $result[$folder2->getId()];
2643
-		$this->assertCount(2, $folder_shares);
2644
-		$this->assertSame($folder2->getId(), $folder_shares[0]->getNodeId());
2645
-		$this->assertSame($folder2->getId(), $folder_shares[1]->getNodeId());
2646
-		$this->assertSame(IShare::TYPE_LINK, $folder_shares[0]->getShareType());
2647
-		$this->assertSame(IShare::TYPE_GROUP, $folder_shares[1]->getShareType());
2648
-
2649
-		$provider->delete($share1);
2650
-		$provider->delete($share2);
2651
-		$provider->delete($share3);
2652
-		$provider->delete($share4);
2653
-
2654
-		$u1->delete();
2655
-		$u2->delete();
2656
-		$u3->delete();
2657
-		$g1->delete();
2658
-	}
2659
-
2660
-	public function testGetAccessListNoCurrentAccessRequired(): void {
2661
-		$userManager = Server::get(IUserManager::class);
2662
-		$groupManager = Server::get(IGroupManager::class);
2663
-		$rootFolder = Server::get(IRootFolder::class);
2664
-
2665
-		$provider = new DefaultShareProvider(
2666
-			$this->dbConn,
2667
-			$userManager,
2668
-			$groupManager,
2669
-			$rootFolder,
2670
-			$this->mailer,
2671
-			$this->defaults,
2672
-			$this->l10nFactory,
2673
-			$this->urlGenerator,
2674
-			$this->timeFactory,
2675
-			$this->logger,
2676
-			$this->shareManager,
2677
-			$this->config,
2678
-		);
2679
-
2680
-		$u1 = $userManager->createUser('testShare1', 'test');
2681
-		$u2 = $userManager->createUser('testShare2', 'test');
2682
-		$u3 = $userManager->createUser('testShare3', 'test');
2683
-		$u4 = $userManager->createUser('testShare4', 'test');
2684
-		$u5 = $userManager->createUser('testShare5', 'test');
2685
-
2686
-		$g1 = $groupManager->createGroup('group1');
2687
-		$g1->addUser($u3);
2688
-		$g1->addUser($u4);
2689
-
2690
-		$u1Folder = $rootFolder->getUserFolder($u1->getUID());
2691
-		$folder1 = $u1Folder->newFolder('foo');
2692
-		$folder2 = $folder1->newFolder('baz');
2693
-		$file1 = $folder2->newFile('bar');
2694
-
2695
-		$result = $provider->getAccessList([$folder1, $folder2, $file1], false);
2696
-		$this->assertCount(0, $result['users']);
2697
-		$this->assertFalse($result['public']);
2698
-
2699
-		$shareManager = Server::get(IShareManager::class);
2700
-		$share1 = $shareManager->newShare();
2701
-		$share1->setNode($folder1)
2702
-			->setSharedBy($u1->getUID())
2703
-			->setSharedWith($u2->getUID())
2704
-			->setShareOwner($u1->getUID())
2705
-			->setShareType(IShare::TYPE_USER)
2706
-			->setPermissions(Constants::PERMISSION_ALL);
2707
-		$share1 = $this->provider->create($share1);
2708
-		$share1 = $provider->acceptShare($share1, $u2->getUid());
2709
-
2710
-		$share2 = $shareManager->newShare();
2711
-		$share2->setNode($folder2)
2712
-			->setSharedBy($u2->getUID())
2713
-			->setSharedWith($g1->getGID())
2714
-			->setShareOwner($u1->getUID())
2715
-			->setShareType(IShare::TYPE_GROUP)
2716
-			->setPermissions(Constants::PERMISSION_ALL);
2717
-		$share2 = $this->provider->create($share2);
2718
-
2719
-		$shareManager->deleteFromSelf($share2, $u4->getUID());
2720
-
2721
-		$share2 = $provider->acceptShare($share2, $u3->getUid());
2722
-		$share2 = $provider->acceptShare($share2, $u4->getUid());
2723
-
2724
-		$share3 = $shareManager->newShare();
2725
-		$share3->setNode($file1)
2726
-			->setSharedBy($u3->getUID())
2727
-			->setShareOwner($u1->getUID())
2728
-			->setShareType(IShare::TYPE_LINK)
2729
-			->setPermissions(Constants::PERMISSION_READ);
2730
-		$share3 = $this->provider->create($share3);
2731
-
2732
-		$share4 = $shareManager->newShare();
2733
-		$share4->setNode($file1)
2734
-			->setSharedBy($u3->getUID())
2735
-			->setSharedWith($u5->getUID())
2736
-			->setShareOwner($u1->getUID())
2737
-			->setShareType(IShare::TYPE_USER)
2738
-			->setPermissions(Constants::PERMISSION_READ);
2739
-		$share4 = $this->provider->create($share4);
2740
-		$share4 = $provider->acceptShare($share4, $u5->getUid());
2741
-
2742
-		$result = $provider->getAccessList([$folder1, $folder2, $file1], false);
2743
-
2744
-		$this->assertCount(4, $result['users']);
2745
-		$this->assertContains('testShare2', $result['users']);
2746
-		$this->assertContains('testShare3', $result['users']);
2747
-		$this->assertContains('testShare4', $result['users']);
2748
-		$this->assertContains('testShare5', $result['users']);
2749
-		$this->assertTrue($result['public']);
2750
-
2751
-		$provider->delete($share1);
2752
-		$provider->delete($share2);
2753
-		$provider->delete($share3);
2754
-		$provider->delete($share4);
2755
-
2756
-		$u1->delete();
2757
-		$u2->delete();
2758
-		$u3->delete();
2759
-		$u4->delete();
2760
-		$u5->delete();
2761
-		$g1->delete();
2762
-	}
2763
-
2764
-	public function testGetAccessListCurrentAccessRequired(): void {
2765
-		$userManager = Server::get(IUserManager::class);
2766
-		$groupManager = Server::get(IGroupManager::class);
2767
-		$rootFolder = Server::get(IRootFolder::class);
2768
-
2769
-		$provider = new DefaultShareProvider(
2770
-			$this->dbConn,
2771
-			$userManager,
2772
-			$groupManager,
2773
-			$rootFolder,
2774
-			$this->mailer,
2775
-			$this->defaults,
2776
-			$this->l10nFactory,
2777
-			$this->urlGenerator,
2778
-			$this->timeFactory,
2779
-			$this->logger,
2780
-			$this->shareManager,
2781
-			$this->config,
2782
-		);
2783
-
2784
-		$u1 = $userManager->createUser('testShare1', 'test');
2785
-		$u2 = $userManager->createUser('testShare2', 'test');
2786
-		$u3 = $userManager->createUser('testShare3', 'test');
2787
-		$u4 = $userManager->createUser('testShare4', 'test');
2788
-		$u5 = $userManager->createUser('testShare5', 'test');
2789
-
2790
-		$g1 = $groupManager->createGroup('group1');
2791
-		$g1->addUser($u3);
2792
-		$g1->addUser($u4);
2793
-
2794
-		$u1Folder = $rootFolder->getUserFolder($u1->getUID());
2795
-		$folder1 = $u1Folder->newFolder('foo');
2796
-		$folder2 = $folder1->newFolder('baz');
2797
-		$file1 = $folder2->newFile('bar');
2798
-
2799
-		$result = $provider->getAccessList([$folder1, $folder2, $file1], false);
2800
-		$this->assertCount(0, $result['users']);
2801
-		$this->assertFalse($result['public']);
2802
-
2803
-		$shareManager = Server::get(IShareManager::class);
2804
-		$share1 = $shareManager->newShare();
2805
-		$share1->setNode($folder1)
2806
-			->setSharedBy($u1->getUID())
2807
-			->setSharedWith($u2->getUID())
2808
-			->setShareOwner($u1->getUID())
2809
-			->setShareType(IShare::TYPE_USER)
2810
-			->setPermissions(Constants::PERMISSION_ALL);
2811
-		$share1 = $this->provider->create($share1);
2812
-		$share1 = $provider->acceptShare($share1, $u2->getUid());
2813
-
2814
-		$share2 = $shareManager->newShare();
2815
-		$share2->setNode($folder2)
2816
-			->setSharedBy($u2->getUID())
2817
-			->setSharedWith($g1->getGID())
2818
-			->setShareOwner($u1->getUID())
2819
-			->setShareType(IShare::TYPE_GROUP)
2820
-			->setPermissions(Constants::PERMISSION_ALL);
2821
-		$share2 = $this->provider->create($share2);
2822
-		$share2 = $provider->acceptShare($share2, $u3->getUid());
2823
-		$share2 = $provider->acceptShare($share2, $u4->getUid());
2824
-
2825
-		$shareManager->deleteFromSelf($share2, $u4->getUID());
2826
-
2827
-		$share3 = $shareManager->newShare();
2828
-		$share3->setNode($file1)
2829
-			->setSharedBy($u3->getUID())
2830
-			->setShareOwner($u1->getUID())
2831
-			->setShareType(IShare::TYPE_LINK)
2832
-			->setPermissions(Constants::PERMISSION_READ);
2833
-		$share3 = $this->provider->create($share3);
2834
-
2835
-		$share4 = $shareManager->newShare();
2836
-		$share4->setNode($file1)
2837
-			->setSharedBy($u3->getUID())
2838
-			->setSharedWith($u5->getUID())
2839
-			->setShareOwner($u1->getUID())
2840
-			->setShareType(IShare::TYPE_USER)
2841
-			->setPermissions(Constants::PERMISSION_READ);
2842
-		$share4 = $this->provider->create($share4);
2843
-		$share4 = $provider->acceptShare($share4, $u5->getUid());
2844
-
2845
-		$result = $provider->getAccessList([$folder1, $folder2, $file1], true);
2846
-
2847
-		$this->assertCount(3, $result['users']);
2848
-		$this->assertArrayHasKey('testShare2', $result['users']);
2849
-		$this->assertArrayHasKey('testShare3', $result['users']);
2850
-		$this->assertArrayHasKey('testShare5', $result['users']);
2851
-		$this->assertTrue($result['public']);
2852
-
2853
-		$provider->delete($share1);
2854
-		$provider->delete($share2);
2855
-		$provider->delete($share3);
2856
-		$provider->delete($share4);
2857
-
2858
-		$u1->delete();
2859
-		$u2->delete();
2860
-		$u3->delete();
2861
-		$u4->delete();
2862
-		$u5->delete();
2863
-		$g1->delete();
2864
-	}
2865
-
2866
-	public function testGetAllShares(): void {
2867
-		$qb = $this->dbConn->getQueryBuilder();
2868
-
2869
-		$qb->insert('share')
2870
-			->values([
2871
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
2872
-				'share_with' => $qb->expr()->literal('sharedWith1'),
2873
-				'uid_owner' => $qb->expr()->literal('shareOwner1'),
2874
-				'uid_initiator' => $qb->expr()->literal('sharedBy1'),
2875
-				'item_type' => $qb->expr()->literal('file'),
2876
-				'file_source' => $qb->expr()->literal(42),
2877
-				'file_target' => $qb->expr()->literal('myTarget1'),
2878
-				'permissions' => $qb->expr()->literal(13),
2879
-			]);
2880
-		$qb->executeStatement();
2881
-
2882
-		$id1 = $qb->getLastInsertId();
2883
-
2884
-		$qb->insert('share')
2885
-			->values([
2886
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
2887
-				'share_with' => $qb->expr()->literal('sharedWith2'),
2888
-				'uid_owner' => $qb->expr()->literal('shareOwner2'),
2889
-				'uid_initiator' => $qb->expr()->literal('sharedBy2'),
2890
-				'item_type' => $qb->expr()->literal('file'),
2891
-				'file_source' => $qb->expr()->literal(43),
2892
-				'file_target' => $qb->expr()->literal('myTarget2'),
2893
-				'permissions' => $qb->expr()->literal(14),
2894
-			]);
2895
-		$qb->executeStatement();
2896
-
2897
-		$id2 = $qb->getLastInsertId();
2898
-
2899
-		$qb->insert('share')
2900
-			->values([
2901
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
2902
-				'token' => $qb->expr()->literal('token3'),
2903
-				'uid_owner' => $qb->expr()->literal('shareOwner3'),
2904
-				'uid_initiator' => $qb->expr()->literal('sharedBy3'),
2905
-				'item_type' => $qb->expr()->literal('file'),
2906
-				'file_source' => $qb->expr()->literal(44),
2907
-				'file_target' => $qb->expr()->literal('myTarget3'),
2908
-				'permissions' => $qb->expr()->literal(15),
2909
-			]);
2910
-		$qb->executeStatement();
2911
-
2912
-		$id3 = $qb->getLastInsertId();
2913
-
2914
-		$qb->insert('share')
2915
-			->values([
2916
-				'share_type' => $qb->expr()->literal(IShare::TYPE_EMAIL),
2917
-				'share_with' => $qb->expr()->literal('shareOwner4'),
2918
-				'token' => $qb->expr()->literal('token4'),
2919
-				'uid_owner' => $qb->expr()->literal('shareOwner4'),
2920
-				'uid_initiator' => $qb->expr()->literal('sharedBy4'),
2921
-				'item_type' => $qb->expr()->literal('file'),
2922
-				'file_source' => $qb->expr()->literal(45),
2923
-				'file_target' => $qb->expr()->literal('myTarget4'),
2924
-				'permissions' => $qb->expr()->literal(16),
2925
-			]);
2926
-		$qb->executeStatement();
2927
-
2928
-		$id4 = $qb->getLastInsertId();
2929
-
2930
-		$qb->insert('share')
2931
-			->values([
2932
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
2933
-				'token' => $qb->expr()->literal('token5'),
2934
-				'uid_owner' => $qb->expr()->literal('shareOwner5'),
2935
-				'uid_initiator' => $qb->expr()->literal('sharedBy5'),
2936
-				'item_type' => $qb->expr()->literal('file'),
2937
-				'file_source' => $qb->expr()->literal(46),
2938
-				'file_target' => $qb->expr()->literal('myTarget5'),
2939
-				'permissions' => $qb->expr()->literal(17),
2940
-			]);
2941
-		$qb->executeStatement();
2942
-
2943
-		$id5 = $qb->getLastInsertId();
2944
-
2945
-		$ownerPath1 = $this->createMock(File::class);
2946
-		$shareOwner1Folder = $this->createMock(Folder::class);
2947
-		$shareOwner1Folder->method('getFirstNodeById')->willReturn($ownerPath1);
2948
-
2949
-		$ownerPath2 = $this->createMock(File::class);
2950
-		$shareOwner2Folder = $this->createMock(Folder::class);
2951
-		$shareOwner2Folder->method('getFirstNodeById')->willReturn($ownerPath2);
2952
-
2953
-		$ownerPath3 = $this->createMock(File::class);
2954
-		$shareOwner3Folder = $this->createMock(Folder::class);
2955
-		$shareOwner3Folder->method('getFirstNodeById')->willReturn($ownerPath3);
2956
-
2957
-		$ownerPath4 = $this->createMock(File::class);
2958
-		$shareOwner4Folder = $this->createMock(Folder::class);
2959
-		$shareOwner4Folder->method('getFirstNodeById')->willReturn($ownerPath4);
2960
-
2961
-		$ownerPath5 = $this->createMock(File::class);
2962
-		$shareOwner5Folder = $this->createMock(Folder::class);
2963
-		$shareOwner5Folder->method('getFirstNodeById')->willReturn($ownerPath5);
2964
-
2965
-		$this->rootFolder
2966
-			->method('getUserFolder')
2967
-			->willReturnMap(
2968
-				[
2969
-					['shareOwner1', $shareOwner1Folder],
2970
-					['shareOwner2', $shareOwner2Folder],
2971
-					['shareOwner3', $shareOwner3Folder],
2972
-					['shareOwner4', $shareOwner4Folder],
2973
-					['shareOwner5', $shareOwner5Folder],
2974
-				]
2975
-			);
2976
-
2977
-		$shares = iterator_to_array($this->provider->getAllShares());
2978
-		$this->assertEquals(4, count($shares));
2979
-
2980
-		$share = $shares[0];
2981
-
2982
-		// We fetch the node so the root folder is eventually called
2983
-
2984
-		$this->assertEquals($id1, $share->getId());
2985
-		$this->assertEquals(IShare::TYPE_USER, $share->getShareType());
2986
-		$this->assertEquals('sharedWith1', $share->getSharedWith());
2987
-		$this->assertEquals('sharedBy1', $share->getSharedBy());
2988
-		$this->assertEquals('shareOwner1', $share->getShareOwner());
2989
-		$this->assertEquals($ownerPath1, $share->getNode());
2990
-		$this->assertEquals(13, $share->getPermissions());
2991
-		$this->assertEquals(null, $share->getToken());
2992
-		$this->assertEquals('myTarget1', $share->getTarget());
2993
-
2994
-		$share = $shares[1];
2995
-
2996
-		$this->assertEquals($id2, $share->getId());
2997
-		$this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
2998
-		$this->assertEquals('sharedWith2', $share->getSharedWith());
2999
-		$this->assertEquals('sharedBy2', $share->getSharedBy());
3000
-		$this->assertEquals('shareOwner2', $share->getShareOwner());
3001
-		$this->assertEquals($ownerPath2, $share->getNode());
3002
-		$this->assertEquals(14, $share->getPermissions());
3003
-		$this->assertEquals(null, $share->getToken());
3004
-		$this->assertEquals('myTarget2', $share->getTarget());
3005
-
3006
-		$share = $shares[2];
3007
-
3008
-		$this->assertEquals($id3, $share->getId());
3009
-		$this->assertEquals(IShare::TYPE_LINK, $share->getShareType());
3010
-		$this->assertEquals(null, $share->getSharedWith());
3011
-		$this->assertEquals('sharedBy3', $share->getSharedBy());
3012
-		$this->assertEquals('shareOwner3', $share->getShareOwner());
3013
-		$this->assertEquals($ownerPath3, $share->getNode());
3014
-		$this->assertEquals(15, $share->getPermissions());
3015
-		$this->assertEquals('token3', $share->getToken());
3016
-		$this->assertEquals('myTarget3', $share->getTarget());
3017
-
3018
-		$share = $shares[3];
3019
-
3020
-		$this->assertEquals($id5, $share->getId());
3021
-		$this->assertEquals(IShare::TYPE_LINK, $share->getShareType());
3022
-		$this->assertEquals(null, $share->getSharedWith());
3023
-		$this->assertEquals('sharedBy5', $share->getSharedBy());
3024
-		$this->assertEquals('shareOwner5', $share->getShareOwner());
3025
-		$this->assertEquals($ownerPath5, $share->getNode());
3026
-		$this->assertEquals(17, $share->getPermissions());
3027
-		$this->assertEquals('token5', $share->getToken());
3028
-		$this->assertEquals('myTarget5', $share->getTarget());
3029
-	}
3030
-
3031
-
3032
-	public function testGetSharesByPath(): void {
3033
-		$qb = $this->dbConn->getQueryBuilder();
3034
-
3035
-		$qb->insert('share')
3036
-			->values([
3037
-				'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
3038
-				'uid_owner' => $qb->expr()->literal('user1'),
3039
-				'uid_initiator' => $qb->expr()->literal('user1'),
3040
-				'share_with' => $qb->expr()->literal('user2'),
3041
-				'item_type' => $qb->expr()->literal('file'),
3042
-				'file_source' => $qb->expr()->literal(1),
3043
-			]);
3044
-		$qb->executeStatement();
3045
-
3046
-		$id1 = $qb->getLastInsertId();
3047
-
3048
-		$qb->insert('share')
3049
-			->values([
3050
-				'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
3051
-				'uid_owner' => $qb->expr()->literal('user1'),
3052
-				'uid_initiator' => $qb->expr()->literal('user1'),
3053
-				'share_with' => $qb->expr()->literal('user2'),
3054
-				'item_type' => $qb->expr()->literal('file'),
3055
-				'file_source' => $qb->expr()->literal(1),
3056
-			]);
3057
-		$qb->executeStatement();
3058
-
3059
-		$id2 = $qb->getLastInsertId();
3060
-
3061
-		$qb->insert('share')
3062
-			->values([
3063
-				'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
3064
-				'uid_owner' => $qb->expr()->literal('user1'),
3065
-				'uid_initiator' => $qb->expr()->literal('user1'),
3066
-				'share_with' => $qb->expr()->literal('user2'),
3067
-				'item_type' => $qb->expr()->literal('file'),
3068
-				'file_source' => $qb->expr()->literal(1),
3069
-			]);
3070
-		$qb->executeStatement();
3071
-
3072
-		$id3 = $qb->getLastInsertId();
3073
-
3074
-		$ownerPath1 = $this->createMock(File::class);
3075
-		$shareOwner1Folder = $this->createMock(Folder::class);
3076
-		$shareOwner1Folder->method('getFirstNodeById')->willReturn($ownerPath1);
3077
-
3078
-		$ownerPath2 = $this->createMock(File::class);
3079
-		$shareOwner2Folder = $this->createMock(Folder::class);
3080
-		$shareOwner2Folder->method('getFirstNodeById')->willReturn($ownerPath2);
3081
-
3082
-		$ownerPath3 = $this->createMock(File::class);
3083
-		$shareOwner3Folder = $this->createMock(Folder::class);
3084
-		$shareOwner3Folder->method('getFirstNodeById')->willReturn($ownerPath3);
3085
-
3086
-		$this->rootFolder
3087
-			->method('getUserFolder')
3088
-			->willReturnMap(
3089
-				[
3090
-					['shareOwner1', $shareOwner1Folder],
3091
-					['shareOwner2', $shareOwner2Folder],
3092
-					['shareOwner3', $shareOwner3Folder],
3093
-				]
3094
-			);
3095
-
3096
-		$node = $this->createMock(Node::class);
3097
-		$node
3098
-			->expects($this->once())
3099
-			->method('getId')
3100
-			->willReturn(1);
3101
-
3102
-		$shares = $this->provider->getSharesByPath($node);
3103
-		$this->assertCount(3, $shares);
3104
-
3105
-		$this->assertEquals($id1, $shares[0]->getId());
3106
-		$this->assertEquals(IShare::TYPE_USER, $shares[0]->getShareType());
3107
-
3108
-		$this->assertEquals($id2, $shares[1]->getId());
3109
-		$this->assertEquals(IShare::TYPE_GROUP, $shares[1]->getShareType());
3110
-
3111
-		$this->assertEquals($id3, $shares[2]->getId());
3112
-		$this->assertEquals(IShare::TYPE_LINK, $shares[2]->getShareType());
3113
-	}
1156
+        $qb = $this->dbConn->getQueryBuilder();
1157
+        $qb->insert('share')
1158
+            ->values([
1159
+                'share_type' => $qb->expr()->literal(2),
1160
+                'share_with' => $qb->expr()->literal('user'),
1161
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1162
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1163
+                'item_type' => $qb->expr()->literal('file'),
1164
+                'file_source' => $qb->expr()->literal($fileId),
1165
+                'file_target' => $qb->expr()->literal('userTarget'),
1166
+                'permissions' => $qb->expr()->literal(0),
1167
+                'parent' => $qb->expr()->literal($id),
1168
+            ]);
1169
+        $this->assertEquals(1, $qb->executeStatement());
1170
+
1171
+        $groups = ['sharedWith'];
1172
+
1173
+        $user = $this->createMock(IUser::class);
1174
+        $user->method('getUID')->willReturn('user');
1175
+        $owner = $this->createMock(IUser::class);
1176
+        $owner->method('getUID')->willReturn('shareOwner');
1177
+        $initiator = $this->createMock(IUser::class);
1178
+        $initiator->method('getUID')->willReturn('sharedBy');
1179
+
1180
+        $this->userManager->method('get')->willReturnMap([
1181
+            ['user', $user],
1182
+            ['shareOwner', $owner],
1183
+            ['sharedBy', $initiator],
1184
+        ]);
1185
+        $this->groupManager
1186
+            ->method('getUserGroupIds')
1187
+            ->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'user' ? $groups : []));
1188
+
1189
+        $file = $this->createMock(File::class);
1190
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1191
+        $this->rootFolder->method('getFirstNodeById')->with($fileId)->willReturn($file);
1192
+
1193
+        $share = $this->provider->getSharedWith('user', IShare::TYPE_GROUP, null, -1, 0);
1194
+        $this->assertCount(1, $share);
1195
+
1196
+        $share = $share[0];
1197
+        $this->assertSame((string)$id, $share->getId());
1198
+        $this->assertSame('sharedWith', $share->getSharedWith());
1199
+        $this->assertSame('shareOwner', $share->getShareOwner());
1200
+        $this->assertSame('sharedBy', $share->getSharedBy());
1201
+        $this->assertSame(IShare::TYPE_GROUP, $share->getShareType());
1202
+        $this->assertSame(0, $share->getPermissions());
1203
+        $this->assertSame('userTarget', $share->getTarget());
1204
+    }
1205
+
1206
+    #[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1207
+    public function testGetSharedWithUserWithNode($storageStringId, $fileName1, $fileName2): void {
1208
+        $storageId = $this->createTestStorageEntry($storageStringId);
1209
+        $fileId = $this->createTestFileEntry($fileName1, $storageId);
1210
+        $fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1211
+        $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user1',
1212
+            'file', $fileId, 'myTarget', 31, null, null, null);
1213
+        $id = $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user1',
1214
+            'file', $fileId2, 'myTarget', 31, null, null, null);
1215
+
1216
+        $user0 = $this->createMock(IUser::class);
1217
+        $user0->method('getUID')->willReturn('user0');
1218
+        $user0->method('getDisplayName')->willReturn('user0');
1219
+        $user1 = $this->createMock(IUser::class);
1220
+        $user1->method('getUID')->willReturn('user1');
1221
+        $user0->method('getDisplayName')->willReturn('user0');
1222
+
1223
+        $this->userManager->method('get')->willReturnMap([
1224
+            ['user0', $user0],
1225
+            ['user1', $user1],
1226
+        ]);
1227
+
1228
+        $file = $this->createMock(File::class);
1229
+        $file->method('getId')->willReturn($fileId2);
1230
+
1231
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1232
+        $this->rootFolder->method('getFirstNodeById')->with($fileId2)->willReturn($file);
1233
+
1234
+        $share = $this->provider->getSharedWith('user0', IShare::TYPE_USER, $file, -1, 0);
1235
+        $this->assertCount(1, $share);
1236
+
1237
+        $share = $share[0];
1238
+        $this->assertEquals($id, $share->getId());
1239
+        $this->assertSame('user0', $share->getSharedWith());
1240
+        $this->assertSame('user1', $share->getShareOwner());
1241
+        $this->assertSame('user1', $share->getSharedBy());
1242
+        $this->assertSame($file, $share->getNode());
1243
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1244
+    }
1245
+
1246
+    #[\PHPUnit\Framework\Attributes\DataProvider('storageAndFileNameProvider')]
1247
+    public function testGetSharedWithGroupWithNode($storageStringId, $fileName1, $fileName2): void {
1248
+        $storageId = $this->createTestStorageEntry($storageStringId);
1249
+        $fileId = $this->createTestFileEntry($fileName1, $storageId);
1250
+        $fileId2 = $this->createTestFileEntry($fileName2, $storageId);
1251
+        $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user1',
1252
+            'file', $fileId, 'myTarget', 31, null, null, null);
1253
+        $id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user1',
1254
+            'file', $fileId2, 'myTarget', 31, null, null, null);
1255
+
1256
+        $user0 = $this->createMock(IUser::class);
1257
+        $user0->method('getUID')->willReturn('user0');
1258
+        $user1 = $this->createMock(IUser::class);
1259
+        $user1->method('getUID')->willReturn('user1');
1260
+
1261
+        $this->userManager->method('get')->willReturnMap([
1262
+            ['user0', $user0],
1263
+            ['user1', $user1],
1264
+        ]);
1265
+
1266
+        $this->groupManager
1267
+            ->method('getUserGroupIds')
1268
+            ->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'user0' ? ['group0'] : []));
1269
+
1270
+        $node = $this->createMock(Folder::class);
1271
+        $node->method('getId')->willReturn($fileId2);
1272
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1273
+        $this->rootFolder->method('getFirstNodeById')->with($fileId2)->willReturn($node);
1274
+
1275
+        $share = $this->provider->getSharedWith('user0', IShare::TYPE_GROUP, $node, -1, 0);
1276
+        $this->assertCount(1, $share);
1277
+
1278
+        $share = $share[0];
1279
+        $this->assertEquals($id, $share->getId());
1280
+        $this->assertSame('group0', $share->getSharedWith());
1281
+        $this->assertSame('user1', $share->getShareOwner());
1282
+        $this->assertSame('user1', $share->getSharedBy());
1283
+        $this->assertSame($node, $share->getNode());
1284
+        $this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
1285
+    }
1286
+
1287
+    public static function shareTypesProvider(): array {
1288
+        return [
1289
+            [IShare::TYPE_USER, false],
1290
+            [IShare::TYPE_GROUP, false],
1291
+            [IShare::TYPE_USER, true],
1292
+            [IShare::TYPE_GROUP, true],
1293
+        ];
1294
+    }
1295
+
1296
+    #[\PHPUnit\Framework\Attributes\DataProvider('shareTypesProvider')]
1297
+    public function testGetSharedWithWithDeletedFile($shareType, $trashed): void {
1298
+        if ($trashed) {
1299
+            // exists in database but is in trash
1300
+            $storageId = $this->createTestStorageEntry('home::shareOwner');
1301
+            $deletedFileId = $this->createTestFileEntry('files_trashbin/files/test.txt.d1465553223', $storageId);
1302
+        } else {
1303
+            // fileid that doesn't exist in the database
1304
+            $deletedFileId = 123;
1305
+        }
1306
+        $qb = $this->dbConn->getQueryBuilder();
1307
+        $qb->insert('share')
1308
+            ->values([
1309
+                'share_type' => $qb->expr()->literal($shareType),
1310
+                'share_with' => $qb->expr()->literal('sharedWith'),
1311
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1312
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1313
+                'item_type' => $qb->expr()->literal('file'),
1314
+                'file_source' => $qb->expr()->literal($deletedFileId),
1315
+                'file_target' => $qb->expr()->literal('myTarget'),
1316
+                'permissions' => $qb->expr()->literal(13),
1317
+            ]);
1318
+        $this->assertEquals(1, $qb->executeStatement());
1319
+
1320
+        $file = $this->createMock(File::class);
1321
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1322
+        $this->rootFolder->method('getFirstNodeById')->with($deletedFileId)->willReturn($file);
1323
+
1324
+        $groups = [];
1325
+        foreach (range(0, 100) as $i) {
1326
+            $groups[] = 'group' . $i;
1327
+        }
1328
+
1329
+        $groups[] = 'sharedWith';
1330
+
1331
+        $user = $this->createMock(IUser::class);
1332
+        $user->method('getUID')->willReturn('sharedWith');
1333
+        $owner = $this->createMock(IUser::class);
1334
+        $owner->method('getUID')->willReturn('shareOwner');
1335
+        $initiator = $this->createMock(IUser::class);
1336
+        $initiator->method('getUID')->willReturn('sharedBy');
1337
+
1338
+        $this->userManager->method('get')->willReturnMap([
1339
+            ['sharedWith', $user],
1340
+            ['shareOwner', $owner],
1341
+            ['sharedBy', $initiator],
1342
+        ]);
1343
+        $this->groupManager
1344
+            ->method('getUserGroupIds')
1345
+            ->willReturnCallback(fn (IUser $user) => ($user->getUID() === 'sharedWith' ? $groups : []));
1346
+
1347
+        $share = $this->provider->getSharedWith('sharedWith', $shareType, null, 1, 0);
1348
+        $this->assertCount(0, $share);
1349
+    }
1350
+
1351
+    public function testGetSharesBy(): void {
1352
+        $qb = $this->dbConn->getQueryBuilder();
1353
+        $qb->insert('share')
1354
+            ->values([
1355
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1356
+                'share_with' => $qb->expr()->literal('sharedWith'),
1357
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1358
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1359
+                'item_type' => $qb->expr()->literal('file'),
1360
+                'file_source' => $qb->expr()->literal(42),
1361
+                'file_target' => $qb->expr()->literal('myTarget'),
1362
+                'permissions' => $qb->expr()->literal(13),
1363
+            ]);
1364
+        $this->assertEquals(1, $qb->executeStatement());
1365
+        $id = $qb->getLastInsertId();
1366
+
1367
+        $qb = $this->dbConn->getQueryBuilder();
1368
+        $qb->insert('share')
1369
+            ->values([
1370
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1371
+                'share_with' => $qb->expr()->literal('sharedWith'),
1372
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1373
+                'uid_initiator' => $qb->expr()->literal('sharedBy2'),
1374
+                'item_type' => $qb->expr()->literal('file'),
1375
+                'file_source' => $qb->expr()->literal(42),
1376
+                'file_target' => $qb->expr()->literal('userTarget'),
1377
+                'permissions' => $qb->expr()->literal(0),
1378
+                'parent' => $qb->expr()->literal($id),
1379
+            ]);
1380
+        $this->assertEquals(1, $qb->executeStatement());
1381
+
1382
+        $file = $this->createMock(File::class);
1383
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1384
+        $this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
1385
+
1386
+        $share = $this->provider->getSharesBy('sharedBy', IShare::TYPE_USER, null, false, 1, 0);
1387
+        $this->assertCount(1, $share);
1388
+
1389
+        /** @var IShare $share */
1390
+        $share = $share[0];
1391
+        $this->assertEquals($id, $share->getId());
1392
+        $this->assertEquals('sharedWith', $share->getSharedWith());
1393
+        $this->assertEquals('shareOwner', $share->getShareOwner());
1394
+        $this->assertEquals('sharedBy', $share->getSharedBy());
1395
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1396
+        $this->assertEquals(13, $share->getPermissions());
1397
+        $this->assertEquals('myTarget', $share->getTarget());
1398
+    }
1399
+
1400
+    public function testGetSharesNode(): void {
1401
+        $qb = $this->dbConn->getQueryBuilder();
1402
+        $qb->insert('share')
1403
+            ->values([
1404
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1405
+                'share_with' => $qb->expr()->literal('sharedWith'),
1406
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1407
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1408
+                'item_type' => $qb->expr()->literal('file'),
1409
+                'file_source' => $qb->expr()->literal(42),
1410
+                'file_target' => $qb->expr()->literal('myTarget'),
1411
+                'permissions' => $qb->expr()->literal(13),
1412
+            ]);
1413
+        $this->assertEquals(1, $qb->executeStatement());
1414
+        $id = $qb->getLastInsertId();
1415
+
1416
+        $qb = $this->dbConn->getQueryBuilder();
1417
+        $qb->insert('share')
1418
+            ->values([
1419
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1420
+                'share_with' => $qb->expr()->literal('sharedWith'),
1421
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1422
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1423
+                'item_type' => $qb->expr()->literal('file'),
1424
+                'file_source' => $qb->expr()->literal(43),
1425
+                'file_target' => $qb->expr()->literal('userTarget'),
1426
+                'permissions' => $qb->expr()->literal(0),
1427
+                'parent' => $qb->expr()->literal($id),
1428
+            ]);
1429
+        $this->assertEquals(1, $qb->executeStatement());
1430
+
1431
+        $file = $this->createMock(File::class);
1432
+        $file->method('getId')->willReturn(42);
1433
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1434
+        $this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
1435
+
1436
+        $share = $this->provider->getSharesBy('sharedBy', IShare::TYPE_USER, $file, false, 1, 0);
1437
+        $this->assertCount(1, $share);
1438
+
1439
+        /** @var IShare $share */
1440
+        $share = $share[0];
1441
+        $this->assertEquals($id, $share->getId());
1442
+        $this->assertEquals('sharedWith', $share->getSharedWith());
1443
+        $this->assertEquals('shareOwner', $share->getShareOwner());
1444
+        $this->assertEquals('sharedBy', $share->getSharedBy());
1445
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1446
+        $this->assertEquals(13, $share->getPermissions());
1447
+        $this->assertEquals('myTarget', $share->getTarget());
1448
+    }
1449
+
1450
+    public function testGetSharesReshare(): void {
1451
+        $qb = $this->dbConn->getQueryBuilder();
1452
+        $qb->insert('share')
1453
+            ->values([
1454
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1455
+                'share_with' => $qb->expr()->literal('sharedWith'),
1456
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1457
+                'uid_initiator' => $qb->expr()->literal('shareOwner'),
1458
+                'item_type' => $qb->expr()->literal('file'),
1459
+                'file_source' => $qb->expr()->literal(42),
1460
+                'file_target' => $qb->expr()->literal('myTarget'),
1461
+                'permissions' => $qb->expr()->literal(13),
1462
+            ]);
1463
+        $this->assertEquals(1, $qb->executeStatement());
1464
+        $id1 = $qb->getLastInsertId();
1465
+
1466
+        $qb = $this->dbConn->getQueryBuilder();
1467
+        $qb->insert('share')
1468
+            ->values([
1469
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1470
+                'share_with' => $qb->expr()->literal('sharedWith'),
1471
+                'uid_owner' => $qb->expr()->literal('shareOwner'),
1472
+                'uid_initiator' => $qb->expr()->literal('sharedBy'),
1473
+                'item_type' => $qb->expr()->literal('file'),
1474
+                'file_source' => $qb->expr()->literal(42),
1475
+                'file_target' => $qb->expr()->literal('userTarget'),
1476
+                'permissions' => $qb->expr()->literal(0),
1477
+            ]);
1478
+        $this->assertEquals(1, $qb->executeStatement());
1479
+        $id2 = $qb->getLastInsertId();
1480
+
1481
+        $file = $this->createMock(File::class);
1482
+        $file->method('getId')->willReturn(42);
1483
+        $this->rootFolder->method('getUserFolder')->with('shareOwner')->willReturnSelf();
1484
+        $this->rootFolder->method('getFirstNodeById')->with(42)->willReturn($file);
1485
+
1486
+        $shares = $this->provider->getSharesBy('shareOwner', IShare::TYPE_USER, null, true, -1, 0);
1487
+        $this->assertCount(2, $shares);
1488
+
1489
+        /** @var IShare $share */
1490
+        $share = $shares[0];
1491
+        $this->assertEquals($id1, $share->getId());
1492
+        $this->assertSame('sharedWith', $share->getSharedWith());
1493
+        $this->assertSame('shareOwner', $share->getShareOwner());
1494
+        $this->assertSame('shareOwner', $share->getSharedBy());
1495
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1496
+        $this->assertEquals(13, $share->getPermissions());
1497
+        $this->assertEquals('myTarget', $share->getTarget());
1498
+
1499
+        $share = $shares[1];
1500
+        $this->assertEquals($id2, $share->getId());
1501
+        $this->assertSame('sharedWith', $share->getSharedWith());
1502
+        $this->assertSame('shareOwner', $share->getShareOwner());
1503
+        $this->assertSame('sharedBy', $share->getSharedBy());
1504
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
1505
+        $this->assertEquals(0, $share->getPermissions());
1506
+        $this->assertEquals('userTarget', $share->getTarget());
1507
+    }
1508
+
1509
+    public function testDeleteFromSelfGroupNoCustomShare(): void {
1510
+        $qb = $this->dbConn->getQueryBuilder();
1511
+        $stmt = $qb->insert('share')
1512
+            ->values([
1513
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1514
+                'share_with' => $qb->expr()->literal('group'),
1515
+                'uid_owner' => $qb->expr()->literal('user1'),
1516
+                'uid_initiator' => $qb->expr()->literal('user1'),
1517
+                'item_type' => $qb->expr()->literal('file'),
1518
+                'file_source' => $qb->expr()->literal(1),
1519
+                'file_target' => $qb->expr()->literal('myTarget1'),
1520
+                'permissions' => $qb->expr()->literal(2)
1521
+            ])->executeStatement();
1522
+        $this->assertEquals(1, $stmt);
1523
+        $id = $qb->getLastInsertId();
1524
+
1525
+        $user1 = $this->createMock(IUser::class);
1526
+        $user1->method('getUID')->willReturn('user1');
1527
+        $user2 = $this->createMock(IUser::class);
1528
+        $user2->method('getUID')->willReturn('user2');
1529
+        $this->userManager->method('get')->willReturnMap([
1530
+            ['user1', $user1],
1531
+            ['user2', $user2],
1532
+        ]);
1533
+
1534
+        $group = $this->createMock(IGroup::class);
1535
+        $group->method('getGID')->willReturn('group');
1536
+        $group->method('inGroup')->with($user2)->willReturn(true);
1537
+        $group->method('getDisplayName')->willReturn('group-displayname');
1538
+        $this->groupManager->method('get')->with('group')->willReturn($group);
1539
+
1540
+        $file = $this->createMock(File::class);
1541
+        $file->method('getId')->willReturn(1);
1542
+
1543
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1544
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1545
+
1546
+        $share = $this->provider->getShareById($id);
1547
+
1548
+        $this->provider->deleteFromSelf($share, 'user2');
1549
+
1550
+        $qb = $this->dbConn->getQueryBuilder();
1551
+        $stmt = $qb->select('*')
1552
+            ->from('share')
1553
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2)))
1554
+            ->executeQuery();
1555
+
1556
+        $shares = $stmt->fetchAll();
1557
+        $stmt->closeCursor();
1558
+
1559
+        $this->assertCount(1, $shares);
1560
+        $share2 = $shares[0];
1561
+        $this->assertEquals($id, $share2['parent']);
1562
+        $this->assertEquals(0, $share2['permissions']);
1563
+        $this->assertEquals('user2', $share2['share_with']);
1564
+    }
1565
+
1566
+    public function testDeleteFromSelfGroupAlreadyCustomShare(): void {
1567
+        $qb = $this->dbConn->getQueryBuilder();
1568
+        $stmt = $qb->insert('share')
1569
+            ->values([
1570
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1571
+                'share_with' => $qb->expr()->literal('group'),
1572
+                'uid_owner' => $qb->expr()->literal('user1'),
1573
+                'uid_initiator' => $qb->expr()->literal('user1'),
1574
+                'item_type' => $qb->expr()->literal('file'),
1575
+                'file_source' => $qb->expr()->literal(1),
1576
+                'file_target' => $qb->expr()->literal('myTarget1'),
1577
+                'permissions' => $qb->expr()->literal(2)
1578
+            ])->executeStatement();
1579
+        $this->assertEquals(1, $stmt);
1580
+        $id = $qb->getLastInsertId();
1581
+
1582
+        $qb = $this->dbConn->getQueryBuilder();
1583
+        $stmt = $qb->insert('share')
1584
+            ->values([
1585
+                'share_type' => $qb->expr()->literal(2),
1586
+                'share_with' => $qb->expr()->literal('user2'),
1587
+                'uid_owner' => $qb->expr()->literal('user1'),
1588
+                'uid_initiator' => $qb->expr()->literal('user1'),
1589
+                'item_type' => $qb->expr()->literal('file'),
1590
+                'file_source' => $qb->expr()->literal(1),
1591
+                'file_target' => $qb->expr()->literal('myTarget1'),
1592
+                'permissions' => $qb->expr()->literal(2),
1593
+                'parent' => $qb->expr()->literal($id),
1594
+            ])->executeStatement();
1595
+        $this->assertEquals(1, $stmt);
1596
+
1597
+        $user1 = $this->createMock(IUser::class);
1598
+        $user1->method('getUID')->willReturn('user1');
1599
+        $user2 = $this->createMock(IUser::class);
1600
+        $user2->method('getUID')->willReturn('user2');
1601
+        $this->userManager->method('get')->willReturnMap([
1602
+            ['user1', $user1],
1603
+            ['user2', $user2],
1604
+        ]);
1605
+
1606
+        $group = $this->createMock(IGroup::class);
1607
+        $group->method('getGID')->willReturn('group');
1608
+        $group->method('inGroup')->with($user2)->willReturn(true);
1609
+        $group->method('getDisplayName')->willReturn('group-displayname');
1610
+        $this->groupManager->method('get')->with('group')->willReturn($group);
1611
+
1612
+        $file = $this->createMock(File::class);
1613
+        $file->method('getId')->willReturn(1);
1614
+
1615
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1616
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1617
+
1618
+        $share = $this->provider->getShareById($id);
1619
+
1620
+        $this->provider->deleteFromSelf($share, 'user2');
1621
+
1622
+        $qb = $this->dbConn->getQueryBuilder();
1623
+        $stmt = $qb->select('*')
1624
+            ->from('share')
1625
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(2)))
1626
+            ->executeQuery();
1627
+
1628
+        $shares = $stmt->fetchAll();
1629
+        $stmt->closeCursor();
1630
+
1631
+        $this->assertCount(1, $shares);
1632
+        $share2 = $shares[0];
1633
+        $this->assertEquals($id, $share2['parent']);
1634
+        $this->assertEquals(0, $share2['permissions']);
1635
+        $this->assertEquals('user2', $share2['share_with']);
1636
+    }
1637
+
1638
+
1639
+    public function testDeleteFromSelfGroupUserNotInGroup(): void {
1640
+        $qb = $this->dbConn->getQueryBuilder();
1641
+        $stmt = $qb->insert('share')
1642
+            ->values([
1643
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1644
+                'share_with' => $qb->expr()->literal('group'),
1645
+                'uid_owner' => $qb->expr()->literal('user1'),
1646
+                'uid_initiator' => $qb->expr()->literal('user1'),
1647
+                'item_type' => $qb->expr()->literal('file'),
1648
+                'file_source' => $qb->expr()->literal(1),
1649
+                'file_target' => $qb->expr()->literal('myTarget1'),
1650
+                'permissions' => $qb->expr()->literal(2)
1651
+            ])->executeStatement();
1652
+        $this->assertEquals(1, $stmt);
1653
+        $id = $qb->getLastInsertId();
1654
+
1655
+        $user1 = $this->createMock(IUser::class);
1656
+        $user1->method('getUID')->willReturn('user1');
1657
+        $user2 = $this->createMock(IUser::class);
1658
+        $user2->method('getUID')->willReturn('user2');
1659
+        $this->userManager->method('get')->willReturnMap([
1660
+            ['user1', $user1],
1661
+            ['user2', $user2],
1662
+        ]);
1663
+
1664
+        $group = $this->createMock(IGroup::class);
1665
+        $group->method('getGID')->willReturn('group');
1666
+        $group->method('inGroup')->with($user2)->willReturn(false);
1667
+        $group->method('getDisplayName')->willReturn('group-displayname');
1668
+        $this->groupManager->method('get')->with('group')->willReturn($group);
1669
+
1670
+        $file = $this->createMock(File::class);
1671
+        $file->method('getId')->willReturn(1);
1672
+
1673
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1674
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1675
+
1676
+        $share = $this->provider->getShareById($id);
1677
+
1678
+        $this->provider->deleteFromSelf($share, 'user2');
1679
+    }
1680
+
1681
+
1682
+    public function testDeleteFromSelfGroupDoesNotExist(): void {
1683
+        $this->expectException(ProviderException::class);
1684
+        $this->expectExceptionMessage('Group "group" does not exist');
1685
+
1686
+        $qb = $this->dbConn->getQueryBuilder();
1687
+        $stmt = $qb->insert('share')
1688
+            ->values([
1689
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
1690
+                'share_with' => $qb->expr()->literal('group'),
1691
+                'uid_owner' => $qb->expr()->literal('user1'),
1692
+                'uid_initiator' => $qb->expr()->literal('user1'),
1693
+                'item_type' => $qb->expr()->literal('file'),
1694
+                'file_source' => $qb->expr()->literal(1),
1695
+                'file_target' => $qb->expr()->literal('myTarget1'),
1696
+                'permissions' => $qb->expr()->literal(2)
1697
+            ])->executeStatement();
1698
+        $this->assertEquals(1, $stmt);
1699
+        $id = $qb->getLastInsertId();
1700
+
1701
+        $user1 = $this->createMock(IUser::class);
1702
+        $user1->method('getUID')->willReturn('user1');
1703
+        $user2 = $this->createMock(IUser::class);
1704
+        $user2->method('getUID')->willReturn('user2');
1705
+        $this->userManager->method('get')->willReturnMap([
1706
+            ['user1', $user1],
1707
+            ['user2', $user2],
1708
+        ]);
1709
+
1710
+        $this->groupManager->method('get')->with('group')->willReturn(null);
1711
+
1712
+        $file = $this->createMock(File::class);
1713
+        $file->method('getId')->willReturn(1);
1714
+
1715
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1716
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1717
+
1718
+        $share = $this->provider->getShareById($id);
1719
+
1720
+        $this->provider->deleteFromSelf($share, 'user2');
1721
+    }
1722
+
1723
+    public function testDeleteFromSelfUser(): void {
1724
+        $qb = $this->dbConn->getQueryBuilder();
1725
+        $stmt = $qb->insert('share')
1726
+            ->values([
1727
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1728
+                'share_with' => $qb->expr()->literal('user2'),
1729
+                'uid_owner' => $qb->expr()->literal('user1'),
1730
+                'uid_initiator' => $qb->expr()->literal('user1'),
1731
+                'item_type' => $qb->expr()->literal('file'),
1732
+                'file_source' => $qb->expr()->literal(1),
1733
+                'file_target' => $qb->expr()->literal('myTarget1'),
1734
+                'permissions' => $qb->expr()->literal(2)
1735
+            ])->executeStatement();
1736
+        $this->assertEquals(1, $stmt);
1737
+        $id = $qb->getLastInsertId();
1738
+
1739
+        $user1 = $this->createMock(IUser::class);
1740
+        $user1->method('getUID')->willReturn('user1');
1741
+        $user1->method('getDisplayName')->willReturn('user1');
1742
+        $user2 = $this->createMock(IUser::class);
1743
+        $user2->method('getUID')->willReturn('user2');
1744
+        $user2->method('getDisplayName')->willReturn('user2');
1745
+        $this->userManager->method('get')->willReturnMap([
1746
+            ['user1', $user1],
1747
+            ['user2', $user2],
1748
+        ]);
1749
+
1750
+        $file = $this->createMock(File::class);
1751
+        $file->method('getId')->willReturn(1);
1752
+
1753
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1754
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1755
+
1756
+        $share = $this->provider->getShareById($id);
1757
+
1758
+        $this->provider->deleteFromSelf($share, 'user2');
1759
+
1760
+        $qb = $this->dbConn->getQueryBuilder();
1761
+        $stmt = $qb->select('*')
1762
+            ->from('share')
1763
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
1764
+            ->executeQuery();
1765
+
1766
+        $shares = $stmt->fetchAll();
1767
+        $stmt->closeCursor();
1768
+
1769
+        $this->assertCount(0, $shares);
1770
+    }
1771
+
1772
+
1773
+    public function testDeleteFromSelfUserNotRecipient(): void {
1774
+        $this->expectException(ProviderException::class);
1775
+        $this->expectExceptionMessage('Recipient does not match');
1776
+
1777
+        $qb = $this->dbConn->getQueryBuilder();
1778
+        $stmt = $qb->insert('share')
1779
+            ->values([
1780
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
1781
+                'share_with' => $qb->expr()->literal('user2'),
1782
+                'uid_owner' => $qb->expr()->literal('user1'),
1783
+                'uid_initiator' => $qb->expr()->literal('user1'),
1784
+                'item_type' => $qb->expr()->literal('file'),
1785
+                'file_source' => $qb->expr()->literal(1),
1786
+                'file_target' => $qb->expr()->literal('myTarget1'),
1787
+                'permissions' => $qb->expr()->literal(2)
1788
+            ])->executeStatement();
1789
+        $this->assertEquals(1, $stmt);
1790
+        $id = $qb->getLastInsertId();
1791
+
1792
+        $user1 = $this->createMock(IUser::class);
1793
+        $user1->method('getUID')->willReturn('user1');
1794
+        $user1->method('getDisplayName')->willReturn('user1');
1795
+        $user2 = $this->createMock(IUser::class);
1796
+        $user2->method('getUID')->willReturn('user2');
1797
+        $user2->method('getDisplayName')->willReturn('user2');
1798
+        $user3 = $this->createMock(IUser::class);
1799
+        $this->userManager->method('get')->willReturnMap([
1800
+            ['user1', $user1],
1801
+            ['user2', $user2],
1802
+        ]);
1803
+
1804
+        $file = $this->createMock(File::class);
1805
+        $file->method('getId')->willReturn(1);
1806
+
1807
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1808
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1809
+
1810
+        $share = $this->provider->getShareById($id);
1811
+
1812
+        $this->provider->deleteFromSelf($share, $user3);
1813
+    }
1814
+
1815
+
1816
+    public function testDeleteFromSelfLink(): void {
1817
+        $this->expectException(ProviderException::class);
1818
+        $this->expectExceptionMessage('Invalid shareType');
1819
+
1820
+        $qb = $this->dbConn->getQueryBuilder();
1821
+        $stmt = $qb->insert('share')
1822
+            ->values([
1823
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
1824
+                'uid_owner' => $qb->expr()->literal('user1'),
1825
+                'uid_initiator' => $qb->expr()->literal('user1'),
1826
+                'item_type' => $qb->expr()->literal('file'),
1827
+                'file_source' => $qb->expr()->literal(1),
1828
+                'file_target' => $qb->expr()->literal('myTarget1'),
1829
+                'permissions' => $qb->expr()->literal(2),
1830
+                'token' => $qb->expr()->literal('token'),
1831
+            ])->executeStatement();
1832
+        $this->assertEquals(1, $stmt);
1833
+        $id = $qb->getLastInsertId();
1834
+
1835
+        $user1 = $this->createMock(IUser::class);
1836
+        $user1->method('getUID')->willReturn('user1');
1837
+        $this->userManager->method('get')->willReturnMap([
1838
+            ['user1', $user1],
1839
+        ]);
1840
+
1841
+        $file = $this->createMock(File::class);
1842
+        $file->method('getId')->willReturn(1);
1843
+
1844
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
1845
+        $this->rootFolder->method('getFirstNodeById')->with(1)->willReturn($file);
1846
+
1847
+        $share = $this->provider->getShareById($id);
1848
+
1849
+        $this->provider->deleteFromSelf($share, $user1);
1850
+    }
1851
+
1852
+    public function testUpdateUser(): void {
1853
+        $id = $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user2',
1854
+            'file', 42, 'target', 31, null, null);
1855
+
1856
+        $users = [];
1857
+        for ($i = 0; $i < 6; $i++) {
1858
+            $user = $this->createMock(IUser::class);
1859
+            $user->method('getUID')->willReturn('user' . $i);
1860
+            $user->method('getDisplayName')->willReturn('user' . $i);
1861
+            $users['user' . $i] = $user;
1862
+        }
1863
+
1864
+        $this->userManager->method('get')->willReturnCallback(
1865
+            function ($userId) use ($users) {
1866
+                return $users[$userId];
1867
+            }
1868
+        );
1869
+
1870
+        $file1 = $this->createMock(File::class);
1871
+        $file1->method('getId')->willReturn(42);
1872
+        $file2 = $this->createMock(File::class);
1873
+        $file2->method('getId')->willReturn(43);
1874
+
1875
+        $folder1 = $this->createMock(Folder::class);
1876
+        $folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
1877
+        $folder2 = $this->createMock(Folder::class);
1878
+        $folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
1879
+
1880
+        $this->rootFolder->method('getUserFolder')->willReturnMap([
1881
+            ['user2', $folder1],
1882
+            ['user5', $folder2],
1883
+        ]);
1884
+
1885
+        $share = $this->provider->getShareById($id);
1886
+
1887
+        $share->setSharedWith('user3');
1888
+        $share->setSharedBy('user4');
1889
+        $share->setShareOwner('user5');
1890
+        $share->setNode($file2);
1891
+        $share->setPermissions(1);
1892
+
1893
+        $share2 = $this->provider->update($share);
1894
+
1895
+        $this->assertEquals($id, $share2->getId());
1896
+        $this->assertSame('user3', $share2->getSharedWith());
1897
+        $this->assertSame('user4', $share2->getSharedBy());
1898
+        $this->assertSame('user5', $share2->getShareOwner());
1899
+        $this->assertSame(1, $share2->getPermissions());
1900
+
1901
+        $share2 = $this->provider->getShareById($id);
1902
+
1903
+        $this->assertEquals($id, $share2->getId());
1904
+        $this->assertSame('user3', $share2->getSharedWith());
1905
+        $this->assertSame('user4', $share2->getSharedBy());
1906
+        $this->assertSame('user5', $share2->getShareOwner());
1907
+        $this->assertSame(1, $share2->getPermissions());
1908
+    }
1909
+
1910
+    public function testUpdateLink(): void {
1911
+        $id = $this->addShareToDB(IShare::TYPE_LINK, null, 'user1', 'user2',
1912
+            'file', 42, 'target', 31, null, null);
1913
+
1914
+        $users = [];
1915
+        for ($i = 0; $i < 6; $i++) {
1916
+            $user = $this->createMock(IUser::class);
1917
+            $user->method('getUID')->willReturn('user' . $i);
1918
+            $users['user' . $i] = $user;
1919
+        }
1920
+
1921
+        $this->userManager->method('get')->willReturnCallback(
1922
+            function ($userId) use ($users) {
1923
+                return $users[$userId];
1924
+            }
1925
+        );
1926
+
1927
+        $file1 = $this->createMock(File::class);
1928
+        $file1->method('getId')->willReturn(42);
1929
+        $file2 = $this->createMock(File::class);
1930
+        $file2->method('getId')->willReturn(43);
1931
+
1932
+        $folder1 = $this->createMock(Folder::class);
1933
+        $folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
1934
+        $folder2 = $this->createMock(Folder::class);
1935
+        $folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
1936
+
1937
+        $this->rootFolder->method('getUserFolder')->willReturnMap([
1938
+            ['user2', $folder1],
1939
+            ['user5', $folder2],
1940
+        ]);
1941
+
1942
+        $share = $this->provider->getShareById($id);
1943
+
1944
+        $share->setPassword('password');
1945
+        $share->setSendPasswordByTalk(true);
1946
+        $share->setSharedBy('user4');
1947
+        $share->setShareOwner('user5');
1948
+        $share->setNode($file2);
1949
+        $share->setPermissions(1);
1950
+
1951
+        $share2 = $this->provider->update($share);
1952
+
1953
+        $this->assertEquals($id, $share2->getId());
1954
+        $this->assertEquals('password', $share2->getPassword());
1955
+        $this->assertSame(true, $share2->getSendPasswordByTalk());
1956
+        $this->assertSame('user4', $share2->getSharedBy());
1957
+        $this->assertSame('user5', $share2->getShareOwner());
1958
+        $this->assertSame(1, $share2->getPermissions());
1959
+
1960
+        $share2 = $this->provider->getShareById($id);
1961
+
1962
+        $this->assertEquals($id, $share2->getId());
1963
+        $this->assertEquals('password', $share2->getPassword());
1964
+        $this->assertSame(true, $share2->getSendPasswordByTalk());
1965
+        $this->assertSame('user4', $share2->getSharedBy());
1966
+        $this->assertSame('user5', $share2->getShareOwner());
1967
+        $this->assertSame(1, $share2->getPermissions());
1968
+    }
1969
+
1970
+    public function testUpdateLinkRemovePassword(): void {
1971
+        $id = $this->addShareToDB(IShare::TYPE_LINK, 'foo', 'user1', 'user2',
1972
+            'file', 42, 'target', 31, null, null);
1973
+
1974
+        $qb = $this->dbConn->getQueryBuilder();
1975
+        $qb->update('share');
1976
+        $qb->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1977
+        $qb->set('password', $qb->createNamedParameter('password'));
1978
+        $this->assertEquals(1, $qb->executeStatement());
1979
+
1980
+        $users = [];
1981
+        for ($i = 0; $i < 6; $i++) {
1982
+            $user = $this->createMock(IUser::class);
1983
+            $user->method('getUID')->willReturn('user' . $i);
1984
+            $users['user' . $i] = $user;
1985
+        }
1986
+
1987
+        $this->userManager->method('get')->willReturnCallback(
1988
+            function ($userId) use ($users) {
1989
+                return $users[$userId];
1990
+            }
1991
+        );
1992
+
1993
+        $file1 = $this->createMock(File::class);
1994
+        $file1->method('getId')->willReturn(42);
1995
+        $file2 = $this->createMock(File::class);
1996
+        $file2->method('getId')->willReturn(43);
1997
+
1998
+        $folder1 = $this->createMock(Folder::class);
1999
+        $folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
2000
+        $folder2 = $this->createMock(Folder::class);
2001
+        $folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
2002
+
2003
+        $this->rootFolder->method('getUserFolder')->willReturnMap([
2004
+            ['user2', $folder1],
2005
+            ['user5', $folder2],
2006
+        ]);
2007
+
2008
+        $share = $this->provider->getShareById($id);
2009
+
2010
+        $share->setPassword(null);
2011
+        $share->setSharedBy('user4');
2012
+        $share->setShareOwner('user5');
2013
+        $share->setNode($file2);
2014
+        $share->setPermissions(1);
2015
+
2016
+        $share2 = $this->provider->update($share);
2017
+
2018
+        $this->assertEquals($id, $share2->getId());
2019
+        $this->assertEquals(null, $share2->getPassword());
2020
+        $this->assertSame('user4', $share2->getSharedBy());
2021
+        $this->assertSame('user5', $share2->getShareOwner());
2022
+        $this->assertSame(1, $share2->getPermissions());
2023
+
2024
+        $share2 = $this->provider->getShareById($id);
2025
+
2026
+        $this->assertEquals($id, $share2->getId());
2027
+        $this->assertEquals(null, $share2->getPassword());
2028
+        $this->assertSame('user4', $share2->getSharedBy());
2029
+        $this->assertSame('user5', $share2->getShareOwner());
2030
+        $this->assertSame(1, $share2->getPermissions());
2031
+    }
2032
+
2033
+    public function testUpdateGroupNoSub(): void {
2034
+        $id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user2',
2035
+            'file', 42, 'target', 31, null, null);
2036
+
2037
+        $users = [];
2038
+        for ($i = 0; $i < 6; $i++) {
2039
+            $user = $this->createMock(IUser::class);
2040
+            $user->method('getUID')->willReturn('user' . $i);
2041
+            $users['user' . $i] = $user;
2042
+        }
2043
+
2044
+        $this->userManager->method('get')->willReturnCallback(
2045
+            function ($userId) use ($users) {
2046
+                return $users[$userId];
2047
+            }
2048
+        );
2049
+
2050
+        $groups = [];
2051
+        for ($i = 0; $i < 2; $i++) {
2052
+            $group = $this->createMock(IGroup::class);
2053
+            $group->method('getGID')->willReturn('group' . $i);
2054
+            $group->method('getDisplayName')->willReturn('group-displayname' . $i);
2055
+            $groups['group' . $i] = $group;
2056
+        }
2057
+
2058
+        $this->groupManager->method('get')->willReturnCallback(
2059
+            function ($groupId) use ($groups) {
2060
+                return $groups[$groupId];
2061
+            }
2062
+        );
2063
+
2064
+        $file1 = $this->createMock(File::class);
2065
+        $file1->method('getId')->willReturn(42);
2066
+        $file2 = $this->createMock(File::class);
2067
+        $file2->method('getId')->willReturn(43);
2068
+
2069
+        $folder1 = $this->createMock(Folder::class);
2070
+        $folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
2071
+        $folder2 = $this->createMock(Folder::class);
2072
+        $folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
2073
+
2074
+        $this->rootFolder->method('getUserFolder')->willReturnMap([
2075
+            ['user2', $folder1],
2076
+            ['user5', $folder2],
2077
+        ]);
2078
+
2079
+        $share = $this->provider->getShareById($id);
2080
+
2081
+        $share->setSharedWith('group0');
2082
+        $share->setSharedBy('user4');
2083
+        $share->setShareOwner('user5');
2084
+        $share->setNode($file2);
2085
+        $share->setPermissions(1);
2086
+
2087
+        $share2 = $this->provider->update($share);
2088
+
2089
+        $this->assertEquals($id, $share2->getId());
2090
+        // Group shares do not allow updating the recipient
2091
+        $this->assertSame('group0', $share2->getSharedWith());
2092
+        $this->assertSame('user4', $share2->getSharedBy());
2093
+        $this->assertSame('user5', $share2->getShareOwner());
2094
+        $this->assertSame(1, $share2->getPermissions());
2095
+
2096
+        $share2 = $this->provider->getShareById($id);
2097
+
2098
+        $this->assertEquals($id, $share2->getId());
2099
+        // Group shares do not allow updating the recipient
2100
+        $this->assertSame('group0', $share2->getSharedWith());
2101
+        $this->assertSame('user4', $share2->getSharedBy());
2102
+        $this->assertSame('user5', $share2->getShareOwner());
2103
+        $this->assertSame(1, $share2->getPermissions());
2104
+    }
2105
+
2106
+    public function testUpdateGroupSubShares(): void {
2107
+        $id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user2',
2108
+            'file', 42, 'target', 31, null, null);
2109
+
2110
+        $id2 = $this->addShareToDB(2, 'user0', 'user1', 'user2',
2111
+            'file', 42, 'mytarget', 31, null, null, $id);
2112
+
2113
+        $id3 = $this->addShareToDB(2, 'user3', 'user1', 'user2',
2114
+            'file', 42, 'mytarget2', 0, null, null, $id);
2115
+
2116
+        $users = [];
2117
+        for ($i = 0; $i < 6; $i++) {
2118
+            $user = $this->createMock(IUser::class);
2119
+            $user->method('getUID')->willReturn('user' . $i);
2120
+            $users['user' . $i] = $user;
2121
+        }
2122
+
2123
+        $this->userManager->method('get')->willReturnCallback(
2124
+            function ($userId) use ($users) {
2125
+                return $users[$userId];
2126
+            }
2127
+        );
2128
+
2129
+        $groups = [];
2130
+        for ($i = 0; $i < 2; $i++) {
2131
+            $group = $this->createMock(IGroup::class);
2132
+            $group->method('getGID')->willReturn('group' . $i);
2133
+            $group->method('getDisplayName')->willReturn('group-displayname' . $i);
2134
+            $groups['group' . $i] = $group;
2135
+        }
2136
+
2137
+        $this->groupManager->method('get')->willReturnCallback(
2138
+            function ($groupId) use ($groups) {
2139
+                return $groups[$groupId];
2140
+            }
2141
+        );
2142
+
2143
+        $file1 = $this->createMock(File::class);
2144
+        $file1->method('getId')->willReturn(42);
2145
+        $file2 = $this->createMock(File::class);
2146
+        $file2->method('getId')->willReturn(43);
2147
+
2148
+        $folder1 = $this->createMock(Folder::class);
2149
+        $folder1->method('getFirstNodeById')->with(42)->willReturn($file1);
2150
+        $folder2 = $this->createMock(Folder::class);
2151
+        $folder2->method('getFirstNodeById')->with(43)->willReturn($file2);
2152
+
2153
+        $this->rootFolder->method('getUserFolder')->willReturnMap([
2154
+            ['user2', $folder1],
2155
+            ['user5', $folder2],
2156
+        ]);
2157
+
2158
+        $share = $this->provider->getShareById($id);
2159
+
2160
+        $share->setSharedWith('group0');
2161
+        $share->setSharedBy('user4');
2162
+        $share->setShareOwner('user5');
2163
+        $share->setNode($file2);
2164
+        $share->setPermissions(1);
2165
+
2166
+        $share2 = $this->provider->update($share);
2167
+
2168
+        $this->assertEquals($id, $share2->getId());
2169
+        // Group shares do not allow updating the recipient
2170
+        $this->assertSame('group0', $share2->getSharedWith());
2171
+        $this->assertSame('user4', $share2->getSharedBy());
2172
+        $this->assertSame('user5', $share2->getShareOwner());
2173
+        $this->assertSame(1, $share2->getPermissions());
2174
+
2175
+        $share2 = $this->provider->getShareById($id);
2176
+
2177
+        $this->assertEquals($id, $share2->getId());
2178
+        // Group shares do not allow updating the recipient
2179
+        $this->assertSame('group0', $share2->getSharedWith());
2180
+        $this->assertSame('user4', $share2->getSharedBy());
2181
+        $this->assertSame('user5', $share2->getShareOwner());
2182
+        $this->assertSame(1, $share2->getPermissions());
2183
+
2184
+        $qb = $this->dbConn->getQueryBuilder();
2185
+        $stmt = $qb->select('*')
2186
+            ->from('share')
2187
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($id)))
2188
+            ->orderBy('id')
2189
+            ->executeQuery();
2190
+
2191
+        $shares = $stmt->fetchAll();
2192
+
2193
+        $this->assertSame('user0', $shares[0]['share_with']);
2194
+        $this->assertSame('user4', $shares[0]['uid_initiator']);
2195
+        $this->assertSame('user5', $shares[0]['uid_owner']);
2196
+        $this->assertSame(1, (int)$shares[0]['permissions']);
2197
+
2198
+        $this->assertSame('user3', $shares[1]['share_with']);
2199
+        $this->assertSame('user4', $shares[1]['uid_initiator']);
2200
+        $this->assertSame('user5', $shares[1]['uid_owner']);
2201
+        $this->assertSame(0, (int)$shares[1]['permissions']);
2202
+
2203
+
2204
+        $stmt->closeCursor();
2205
+    }
2206
+
2207
+    public function testMoveUserShare(): void {
2208
+        $id = $this->addShareToDB(IShare::TYPE_USER, 'user0', 'user1', 'user1', 'file',
2209
+            42, 'mytaret', 31, null, null);
2210
+
2211
+        $user0 = $this->createMock(IUser::class);
2212
+        $user0->method('getUID')->willReturn('user0');
2213
+        $user0->method('getDisplayName')->willReturn('user0');
2214
+        $user1 = $this->createMock(IUser::class);
2215
+        $user1->method('getUID')->willReturn('user1');
2216
+        $user1->method('getDisplayName')->willReturn('user1');
2217
+
2218
+        $this->userManager->method('get')->willReturnMap([
2219
+            ['user0', $user0],
2220
+            ['user1', $user1],
2221
+        ]);
2222
+
2223
+        $file = $this->createMock(File::class);
2224
+        $file->method('getId')->willReturn(42);
2225
+
2226
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
2227
+        $this->rootFolder->method('getFirstNodeById')->willReturn($file);
2228
+
2229
+        $share = $this->provider->getShareById($id, null);
2230
+
2231
+        $share->setTarget('/newTarget');
2232
+        $this->provider->move($share, $user0);
2233
+
2234
+        $share = $this->provider->getShareById($id, null);
2235
+        $this->assertSame('/newTarget', $share->getTarget());
2236
+    }
2237
+
2238
+    public function testMoveGroupShare(): void {
2239
+        $id = $this->addShareToDB(IShare::TYPE_GROUP, 'group0', 'user1', 'user1', 'file',
2240
+            42, 'mytaret', 31, null, null);
2241
+
2242
+        $user0 = $this->createMock(IUser::class);
2243
+        $user0->method('getUID')->willReturn('user0');
2244
+        $user1 = $this->createMock(IUser::class);
2245
+        $user1->method('getUID')->willReturn('user1');
2246
+
2247
+        $group0 = $this->createMock(IGroup::class);
2248
+        $group0->method('getGID')->willReturn('group0');
2249
+        $group0->method('inGroup')->with($user0)->willReturn(true);
2250
+        $group0->method('getDisplayName')->willReturn('group0-displayname');
2251
+
2252
+        $this->groupManager->method('get')->with('group0')->willReturn($group0);
2253
+
2254
+        $this->userManager->method('get')->willReturnMap([
2255
+            ['user0', $user0],
2256
+            ['user1', $user1],
2257
+        ]);
2258
+
2259
+        $folder = $this->createMock(Folder::class);
2260
+        $folder->method('getId')->willReturn(42);
2261
+
2262
+        $this->rootFolder->method('getUserFolder')->with('user1')->willReturnSelf();
2263
+        $this->rootFolder->method('getFirstNodeById')->willReturn($folder);
2264
+
2265
+        $share = $this->provider->getShareById($id, 'user0');
2266
+
2267
+        $share->setTarget('/newTarget');
2268
+        $this->provider->move($share, 'user0');
2269
+
2270
+        $share = $this->provider->getShareById($id, 'user0');
2271
+        $this->assertSame('/newTarget', $share->getTarget());
2272
+
2273
+        $share->setTarget('/ultraNewTarget');
2274
+        $this->provider->move($share, 'user0');
2275
+
2276
+        $share = $this->provider->getShareById($id, 'user0');
2277
+        $this->assertSame('/ultraNewTarget', $share->getTarget());
2278
+    }
2279
+
2280
+    public static function dataDeleteUser(): array {
2281
+        return [
2282
+            [IShare::TYPE_USER, 'a', 'b', 'c', 'a', true],
2283
+            [IShare::TYPE_USER, 'a', 'b', 'c', 'b', false],
2284
+            [IShare::TYPE_USER, 'a', 'b', 'c', 'c', true],
2285
+            [IShare::TYPE_USER, 'a', 'b', 'c', 'd', false],
2286
+            [IShare::TYPE_GROUP, 'a', 'b', 'c', 'a', true],
2287
+            [IShare::TYPE_GROUP, 'a', 'b', 'c', 'b', false],
2288
+            // The group c is still valid but user c is deleted so group share stays
2289
+            [IShare::TYPE_GROUP, 'a', 'b', 'c', 'c', false],
2290
+            [IShare::TYPE_GROUP, 'a', 'b', 'c', 'd', false],
2291
+            [IShare::TYPE_LINK, 'a', 'b', 'c', 'a', true],
2292
+            // To avoid invisible link shares delete initiated link shares as well (see #22327)
2293
+            [IShare::TYPE_LINK, 'a', 'b', 'c', 'b', true],
2294
+            [IShare::TYPE_LINK, 'a', 'b', 'c', 'c', false],
2295
+            [IShare::TYPE_LINK, 'a', 'b', 'c', 'd', false],
2296
+        ];
2297
+    }
2298
+
2299
+    /**
2300
+     *
2301
+     * @param int $type The shareType (user/group/link)
2302
+     * @param string $owner The owner of the share (uid)
2303
+     * @param string $initiator The initiator of the share (uid)
2304
+     * @param string $recipient The recipient of the share (uid/gid/pass)
2305
+     * @param string $deletedUser The user that is deleted
2306
+     * @param bool $rowDeleted Is the row deleted in this setup
2307
+     */
2308
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataDeleteUser')]
2309
+    public function testDeleteUser($type, $owner, $initiator, $recipient, $deletedUser, $rowDeleted): void {
2310
+        $qb = $this->dbConn->getQueryBuilder();
2311
+        $qb->insert('share')
2312
+            ->setValue('share_type', $qb->createNamedParameter($type))
2313
+            ->setValue('uid_owner', $qb->createNamedParameter($owner))
2314
+            ->setValue('uid_initiator', $qb->createNamedParameter($initiator))
2315
+            ->setValue('share_with', $qb->createNamedParameter($recipient))
2316
+            ->setValue('item_type', $qb->createNamedParameter('file'))
2317
+            ->setValue('item_source', $qb->createNamedParameter(42))
2318
+            ->setValue('file_source', $qb->createNamedParameter(42))
2319
+            ->executeStatement();
2320
+
2321
+        $id = $qb->getLastInsertId();
2322
+
2323
+        $this->provider->userDeleted($deletedUser, $type);
2324
+
2325
+        $qb = $this->dbConn->getQueryBuilder();
2326
+        $qb->select('*')
2327
+            ->from('share')
2328
+            ->where(
2329
+                $qb->expr()->eq('id', $qb->createNamedParameter($id))
2330
+            );
2331
+        $cursor = $qb->executeQuery();
2332
+        $data = $cursor->fetchAll();
2333
+        $cursor->closeCursor();
2334
+
2335
+        $this->assertCount($rowDeleted ? 0 : 1, $data);
2336
+    }
2337
+
2338
+    public static function dataDeleteUserGroup(): array {
2339
+        return [
2340
+            ['a', 'b', 'c', 'a', true, true],
2341
+            ['a', 'b', 'c', 'b', false, false],
2342
+            ['a', 'b', 'c', 'c', false, true],
2343
+            ['a', 'b', 'c', 'd', false, false],
2344
+        ];
2345
+    }
2346
+
2347
+    /**
2348
+     *
2349
+     * @param string $owner The owner of the share (uid)
2350
+     * @param string $initiator The initiator of the share (uid)
2351
+     * @param string $recipient The recipient of the usergroup share (uid)
2352
+     * @param string $deletedUser The user that is deleted
2353
+     * @param bool $groupShareDeleted
2354
+     * @param bool $userGroupShareDeleted
2355
+     */
2356
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataDeleteUserGroup')]
2357
+    public function testDeleteUserGroup($owner, $initiator, $recipient, $deletedUser, $groupShareDeleted, $userGroupShareDeleted): void {
2358
+        $qb = $this->dbConn->getQueryBuilder();
2359
+        $qb->insert('share')
2360
+            ->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
2361
+            ->setValue('uid_owner', $qb->createNamedParameter($owner))
2362
+            ->setValue('uid_initiator', $qb->createNamedParameter($initiator))
2363
+            ->setValue('share_with', $qb->createNamedParameter('group'))
2364
+            ->setValue('item_type', $qb->createNamedParameter('file'))
2365
+            ->setValue('item_source', $qb->createNamedParameter(42))
2366
+            ->setValue('file_source', $qb->createNamedParameter(42))
2367
+            ->executeStatement();
2368
+        $groupId = $qb->getLastInsertId();
2369
+
2370
+        $qb = $this->dbConn->getQueryBuilder();
2371
+        $qb->insert('share')
2372
+            ->setValue('share_type', $qb->createNamedParameter(2))
2373
+            ->setValue('uid_owner', $qb->createNamedParameter($owner))
2374
+            ->setValue('uid_initiator', $qb->createNamedParameter($initiator))
2375
+            ->setValue('share_with', $qb->createNamedParameter($recipient))
2376
+            ->setValue('item_type', $qb->createNamedParameter('file'))
2377
+            ->setValue('item_source', $qb->createNamedParameter(42))
2378
+            ->setValue('file_source', $qb->createNamedParameter(42))
2379
+            ->executeStatement();
2380
+        $userGroupId = $qb->getLastInsertId();
2381
+
2382
+        $this->provider->userDeleted($deletedUser, IShare::TYPE_GROUP);
2383
+
2384
+        $qb = $this->dbConn->getQueryBuilder();
2385
+        $qb->select('*')
2386
+            ->from('share')
2387
+            ->where(
2388
+                $qb->expr()->eq('id', $qb->createNamedParameter($userGroupId))
2389
+            );
2390
+        $cursor = $qb->executeQuery();
2391
+        $data = $cursor->fetchAll();
2392
+        $cursor->closeCursor();
2393
+        $this->assertCount($userGroupShareDeleted ? 0 : 1, $data);
2394
+
2395
+        $qb = $this->dbConn->getQueryBuilder();
2396
+        $qb->select('*')
2397
+            ->from('share')
2398
+            ->where(
2399
+                $qb->expr()->eq('id', $qb->createNamedParameter($groupId))
2400
+            );
2401
+        $cursor = $qb->executeQuery();
2402
+        $data = $cursor->fetchAll();
2403
+        $cursor->closeCursor();
2404
+        $this->assertCount($groupShareDeleted ? 0 : 1, $data);
2405
+    }
2406
+
2407
+    public static function dataGroupDeleted(): array {
2408
+        return [
2409
+            [
2410
+                [
2411
+                    'type' => IShare::TYPE_USER,
2412
+                    'recipient' => 'user',
2413
+                    'children' => []
2414
+                ], 'group', false
2415
+            ],
2416
+            [
2417
+                [
2418
+                    'type' => IShare::TYPE_USER,
2419
+                    'recipient' => 'user',
2420
+                    'children' => []
2421
+                ], 'user', false
2422
+            ],
2423
+            [
2424
+                [
2425
+                    'type' => IShare::TYPE_LINK,
2426
+                    'recipient' => 'user',
2427
+                    'children' => []
2428
+                ], 'group', false
2429
+            ],
2430
+            [
2431
+                [
2432
+                    'type' => IShare::TYPE_GROUP,
2433
+                    'recipient' => 'group1',
2434
+                    'children' => [
2435
+                        'foo',
2436
+                        'bar'
2437
+                    ]
2438
+                ], 'group2', false
2439
+            ],
2440
+            [
2441
+                [
2442
+                    'type' => IShare::TYPE_GROUP,
2443
+                    'recipient' => 'group1',
2444
+                    'children' => [
2445
+                        'foo',
2446
+                        'bar'
2447
+                    ]
2448
+                ], 'group1', true
2449
+            ],
2450
+        ];
2451
+    }
2452
+
2453
+    /**
2454
+     *
2455
+     * @param $shares
2456
+     * @param $groupToDelete
2457
+     * @param $shouldBeDeleted
2458
+     */
2459
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataGroupDeleted')]
2460
+    public function testGroupDeleted($shares, $groupToDelete, $shouldBeDeleted): void {
2461
+        $qb = $this->dbConn->getQueryBuilder();
2462
+        $qb->insert('share')
2463
+            ->setValue('share_type', $qb->createNamedParameter($shares['type']))
2464
+            ->setValue('uid_owner', $qb->createNamedParameter('owner'))
2465
+            ->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2466
+            ->setValue('share_with', $qb->createNamedParameter($shares['recipient']))
2467
+            ->setValue('item_type', $qb->createNamedParameter('file'))
2468
+            ->setValue('item_source', $qb->createNamedParameter(42))
2469
+            ->setValue('file_source', $qb->createNamedParameter(42))
2470
+            ->executeStatement();
2471
+        $ids = [$qb->getLastInsertId()];
2472
+
2473
+        foreach ($shares['children'] as $child) {
2474
+            $qb = $this->dbConn->getQueryBuilder();
2475
+            $qb->insert('share')
2476
+                ->setValue('share_type', $qb->createNamedParameter(2))
2477
+                ->setValue('uid_owner', $qb->createNamedParameter('owner'))
2478
+                ->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2479
+                ->setValue('share_with', $qb->createNamedParameter($child))
2480
+                ->setValue('item_type', $qb->createNamedParameter('file'))
2481
+                ->setValue('item_source', $qb->createNamedParameter(42))
2482
+                ->setValue('file_source', $qb->createNamedParameter(42))
2483
+                ->setValue('parent', $qb->createNamedParameter($ids[0]))
2484
+                ->executeStatement();
2485
+            $ids[] = $qb->getLastInsertId();
2486
+        }
2487
+
2488
+        $this->provider->groupDeleted($groupToDelete);
2489
+
2490
+        $qb = $this->dbConn->getQueryBuilder();
2491
+        $cursor = $qb->select('*')
2492
+            ->from('share')
2493
+            ->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
2494
+            ->executeQuery();
2495
+        $data = $cursor->fetchAll();
2496
+        $cursor->closeCursor();
2497
+
2498
+        $this->assertCount($shouldBeDeleted ? 0 : count($ids), $data);
2499
+    }
2500
+
2501
+    public static function dataUserDeletedFromGroup(): array {
2502
+        return [
2503
+            ['group1', 'user1', true],
2504
+            ['group1', 'user2', false],
2505
+            ['group2', 'user1', false],
2506
+        ];
2507
+    }
2508
+
2509
+    /**
2510
+     * Given a group share with 'group1'
2511
+     * And a user specific group share with 'user1'.
2512
+     * User $user is deleted from group $gid.
2513
+     *
2514
+     *
2515
+     * @param string $group
2516
+     * @param string $user
2517
+     * @param bool $toDelete
2518
+     */
2519
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataUserDeletedFromGroup')]
2520
+    public function testUserDeletedFromGroup($group, $user, $toDelete): void {
2521
+        $qb = $this->dbConn->getQueryBuilder();
2522
+        $qb->insert('share')
2523
+            ->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
2524
+            ->setValue('uid_owner', $qb->createNamedParameter('owner'))
2525
+            ->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2526
+            ->setValue('share_with', $qb->createNamedParameter('group1'))
2527
+            ->setValue('item_type', $qb->createNamedParameter('file'))
2528
+            ->setValue('item_source', $qb->createNamedParameter(42))
2529
+            ->setValue('file_source', $qb->createNamedParameter(42));
2530
+        $qb->executeStatement();
2531
+        $id1 = $qb->getLastInsertId();
2532
+
2533
+        $qb = $this->dbConn->getQueryBuilder();
2534
+        $qb->insert('share')
2535
+            ->setValue('share_type', $qb->createNamedParameter(2))
2536
+            ->setValue('uid_owner', $qb->createNamedParameter('owner'))
2537
+            ->setValue('uid_initiator', $qb->createNamedParameter('initiator'))
2538
+            ->setValue('share_with', $qb->createNamedParameter('user1'))
2539
+            ->setValue('item_type', $qb->createNamedParameter('file'))
2540
+            ->setValue('item_source', $qb->createNamedParameter(42))
2541
+            ->setValue('file_source', $qb->createNamedParameter(42))
2542
+            ->setValue('parent', $qb->createNamedParameter($id1));
2543
+        $qb->executeStatement();
2544
+        $id2 = $qb->getLastInsertId();
2545
+
2546
+        $this->provider->userDeletedFromGroup($user, $group);
2547
+
2548
+        $qb = $this->dbConn->getQueryBuilder();
2549
+        $qb->select('*')
2550
+            ->from('share')
2551
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id2)));
2552
+        $cursor = $qb->executeQuery();
2553
+        $data = $cursor->fetchAll();
2554
+        $cursor->closeCursor();
2555
+
2556
+        $this->assertCount($toDelete ? 0 : 1, $data);
2557
+    }
2558
+
2559
+    public function testGetSharesInFolder(): void {
2560
+        $userManager = Server::get(IUserManager::class);
2561
+        $groupManager = Server::get(IGroupManager::class);
2562
+        $rootFolder = Server::get(IRootFolder::class);
2563
+
2564
+        $provider = new DefaultShareProvider(
2565
+            $this->dbConn,
2566
+            $userManager,
2567
+            $groupManager,
2568
+            $rootFolder,
2569
+            $this->mailer,
2570
+            $this->defaults,
2571
+            $this->l10nFactory,
2572
+            $this->urlGenerator,
2573
+            $this->timeFactory,
2574
+            $this->logger,
2575
+            $this->shareManager,
2576
+            $this->config,
2577
+        );
2578
+
2579
+        $password = md5(time());
2580
+
2581
+        $u1 = $userManager->createUser('testShare1', $password);
2582
+        $u2 = $userManager->createUser('testShare2', $password);
2583
+        $u3 = $userManager->createUser('testShare3', $password);
2584
+
2585
+        $g1 = $groupManager->createGroup('group1');
2586
+
2587
+        $u1Folder = $rootFolder->getUserFolder($u1->getUID());
2588
+        $folder1 = $u1Folder->newFolder('foo');
2589
+        $file1 = $folder1->newFile('bar');
2590
+        $folder2 = $folder1->newFolder('baz');
2591
+
2592
+        $shareManager = Server::get(IShareManager::class);
2593
+        $share1 = $shareManager->newShare();
2594
+        $share1->setNode($folder1)
2595
+            ->setSharedBy($u1->getUID())
2596
+            ->setSharedWith($u2->getUID())
2597
+            ->setShareOwner($u1->getUID())
2598
+            ->setShareType(IShare::TYPE_USER)
2599
+            ->setPermissions(Constants::PERMISSION_ALL);
2600
+        $share1 = $this->provider->create($share1);
2601
+
2602
+        $share2 = $shareManager->newShare();
2603
+        $share2->setNode($file1)
2604
+            ->setSharedBy($u2->getUID())
2605
+            ->setSharedWith($u3->getUID())
2606
+            ->setShareOwner($u1->getUID())
2607
+            ->setShareType(IShare::TYPE_USER)
2608
+            ->setPermissions(Constants::PERMISSION_READ);
2609
+        $share2 = $this->provider->create($share2);
2610
+
2611
+        $share3 = $shareManager->newShare();
2612
+        $share3->setNode($folder2)
2613
+            ->setSharedBy($u2->getUID())
2614
+            ->setShareOwner($u1->getUID())
2615
+            ->setShareType(IShare::TYPE_LINK)
2616
+            ->setPermissions(Constants::PERMISSION_READ);
2617
+        $share3 = $this->provider->create($share3);
2618
+
2619
+        $share4 = $shareManager->newShare();
2620
+        $share4->setNode($folder2)
2621
+            ->setSharedBy($u1->getUID())
2622
+            ->setSharedWith($g1->getGID())
2623
+            ->setShareOwner($u1->getUID())
2624
+            ->setShareType(IShare::TYPE_GROUP)
2625
+            ->setPermissions(Constants::PERMISSION_READ);
2626
+        $share4 = $this->provider->create($share4);
2627
+
2628
+        $result = $provider->getSharesInFolder($u1->getUID(), $folder1, false);
2629
+        $this->assertCount(1, $result);
2630
+        $shares = array_pop($result);
2631
+        $this->assertCount(1, $shares);
2632
+        $this->assertSame($folder2->getId(), $shares[0]->getNodeId());
2633
+
2634
+        $result = $provider->getSharesInFolder($u1->getUID(), $folder1, true);
2635
+        $this->assertCount(2, $result);
2636
+
2637
+        $file_shares = $result[$file1->getId()];
2638
+        $this->assertCount(1, $file_shares);
2639
+        $this->assertSame($file1->getId(), $file_shares[0]->getNodeId());
2640
+        $this->assertSame(IShare::TYPE_USER, $file_shares[0]->getShareType());
2641
+
2642
+        $folder_shares = $result[$folder2->getId()];
2643
+        $this->assertCount(2, $folder_shares);
2644
+        $this->assertSame($folder2->getId(), $folder_shares[0]->getNodeId());
2645
+        $this->assertSame($folder2->getId(), $folder_shares[1]->getNodeId());
2646
+        $this->assertSame(IShare::TYPE_LINK, $folder_shares[0]->getShareType());
2647
+        $this->assertSame(IShare::TYPE_GROUP, $folder_shares[1]->getShareType());
2648
+
2649
+        $provider->delete($share1);
2650
+        $provider->delete($share2);
2651
+        $provider->delete($share3);
2652
+        $provider->delete($share4);
2653
+
2654
+        $u1->delete();
2655
+        $u2->delete();
2656
+        $u3->delete();
2657
+        $g1->delete();
2658
+    }
2659
+
2660
+    public function testGetAccessListNoCurrentAccessRequired(): void {
2661
+        $userManager = Server::get(IUserManager::class);
2662
+        $groupManager = Server::get(IGroupManager::class);
2663
+        $rootFolder = Server::get(IRootFolder::class);
2664
+
2665
+        $provider = new DefaultShareProvider(
2666
+            $this->dbConn,
2667
+            $userManager,
2668
+            $groupManager,
2669
+            $rootFolder,
2670
+            $this->mailer,
2671
+            $this->defaults,
2672
+            $this->l10nFactory,
2673
+            $this->urlGenerator,
2674
+            $this->timeFactory,
2675
+            $this->logger,
2676
+            $this->shareManager,
2677
+            $this->config,
2678
+        );
2679
+
2680
+        $u1 = $userManager->createUser('testShare1', 'test');
2681
+        $u2 = $userManager->createUser('testShare2', 'test');
2682
+        $u3 = $userManager->createUser('testShare3', 'test');
2683
+        $u4 = $userManager->createUser('testShare4', 'test');
2684
+        $u5 = $userManager->createUser('testShare5', 'test');
2685
+
2686
+        $g1 = $groupManager->createGroup('group1');
2687
+        $g1->addUser($u3);
2688
+        $g1->addUser($u4);
2689
+
2690
+        $u1Folder = $rootFolder->getUserFolder($u1->getUID());
2691
+        $folder1 = $u1Folder->newFolder('foo');
2692
+        $folder2 = $folder1->newFolder('baz');
2693
+        $file1 = $folder2->newFile('bar');
2694
+
2695
+        $result = $provider->getAccessList([$folder1, $folder2, $file1], false);
2696
+        $this->assertCount(0, $result['users']);
2697
+        $this->assertFalse($result['public']);
2698
+
2699
+        $shareManager = Server::get(IShareManager::class);
2700
+        $share1 = $shareManager->newShare();
2701
+        $share1->setNode($folder1)
2702
+            ->setSharedBy($u1->getUID())
2703
+            ->setSharedWith($u2->getUID())
2704
+            ->setShareOwner($u1->getUID())
2705
+            ->setShareType(IShare::TYPE_USER)
2706
+            ->setPermissions(Constants::PERMISSION_ALL);
2707
+        $share1 = $this->provider->create($share1);
2708
+        $share1 = $provider->acceptShare($share1, $u2->getUid());
2709
+
2710
+        $share2 = $shareManager->newShare();
2711
+        $share2->setNode($folder2)
2712
+            ->setSharedBy($u2->getUID())
2713
+            ->setSharedWith($g1->getGID())
2714
+            ->setShareOwner($u1->getUID())
2715
+            ->setShareType(IShare::TYPE_GROUP)
2716
+            ->setPermissions(Constants::PERMISSION_ALL);
2717
+        $share2 = $this->provider->create($share2);
2718
+
2719
+        $shareManager->deleteFromSelf($share2, $u4->getUID());
2720
+
2721
+        $share2 = $provider->acceptShare($share2, $u3->getUid());
2722
+        $share2 = $provider->acceptShare($share2, $u4->getUid());
2723
+
2724
+        $share3 = $shareManager->newShare();
2725
+        $share3->setNode($file1)
2726
+            ->setSharedBy($u3->getUID())
2727
+            ->setShareOwner($u1->getUID())
2728
+            ->setShareType(IShare::TYPE_LINK)
2729
+            ->setPermissions(Constants::PERMISSION_READ);
2730
+        $share3 = $this->provider->create($share3);
2731
+
2732
+        $share4 = $shareManager->newShare();
2733
+        $share4->setNode($file1)
2734
+            ->setSharedBy($u3->getUID())
2735
+            ->setSharedWith($u5->getUID())
2736
+            ->setShareOwner($u1->getUID())
2737
+            ->setShareType(IShare::TYPE_USER)
2738
+            ->setPermissions(Constants::PERMISSION_READ);
2739
+        $share4 = $this->provider->create($share4);
2740
+        $share4 = $provider->acceptShare($share4, $u5->getUid());
2741
+
2742
+        $result = $provider->getAccessList([$folder1, $folder2, $file1], false);
2743
+
2744
+        $this->assertCount(4, $result['users']);
2745
+        $this->assertContains('testShare2', $result['users']);
2746
+        $this->assertContains('testShare3', $result['users']);
2747
+        $this->assertContains('testShare4', $result['users']);
2748
+        $this->assertContains('testShare5', $result['users']);
2749
+        $this->assertTrue($result['public']);
2750
+
2751
+        $provider->delete($share1);
2752
+        $provider->delete($share2);
2753
+        $provider->delete($share3);
2754
+        $provider->delete($share4);
2755
+
2756
+        $u1->delete();
2757
+        $u2->delete();
2758
+        $u3->delete();
2759
+        $u4->delete();
2760
+        $u5->delete();
2761
+        $g1->delete();
2762
+    }
2763
+
2764
+    public function testGetAccessListCurrentAccessRequired(): void {
2765
+        $userManager = Server::get(IUserManager::class);
2766
+        $groupManager = Server::get(IGroupManager::class);
2767
+        $rootFolder = Server::get(IRootFolder::class);
2768
+
2769
+        $provider = new DefaultShareProvider(
2770
+            $this->dbConn,
2771
+            $userManager,
2772
+            $groupManager,
2773
+            $rootFolder,
2774
+            $this->mailer,
2775
+            $this->defaults,
2776
+            $this->l10nFactory,
2777
+            $this->urlGenerator,
2778
+            $this->timeFactory,
2779
+            $this->logger,
2780
+            $this->shareManager,
2781
+            $this->config,
2782
+        );
2783
+
2784
+        $u1 = $userManager->createUser('testShare1', 'test');
2785
+        $u2 = $userManager->createUser('testShare2', 'test');
2786
+        $u3 = $userManager->createUser('testShare3', 'test');
2787
+        $u4 = $userManager->createUser('testShare4', 'test');
2788
+        $u5 = $userManager->createUser('testShare5', 'test');
2789
+
2790
+        $g1 = $groupManager->createGroup('group1');
2791
+        $g1->addUser($u3);
2792
+        $g1->addUser($u4);
2793
+
2794
+        $u1Folder = $rootFolder->getUserFolder($u1->getUID());
2795
+        $folder1 = $u1Folder->newFolder('foo');
2796
+        $folder2 = $folder1->newFolder('baz');
2797
+        $file1 = $folder2->newFile('bar');
2798
+
2799
+        $result = $provider->getAccessList([$folder1, $folder2, $file1], false);
2800
+        $this->assertCount(0, $result['users']);
2801
+        $this->assertFalse($result['public']);
2802
+
2803
+        $shareManager = Server::get(IShareManager::class);
2804
+        $share1 = $shareManager->newShare();
2805
+        $share1->setNode($folder1)
2806
+            ->setSharedBy($u1->getUID())
2807
+            ->setSharedWith($u2->getUID())
2808
+            ->setShareOwner($u1->getUID())
2809
+            ->setShareType(IShare::TYPE_USER)
2810
+            ->setPermissions(Constants::PERMISSION_ALL);
2811
+        $share1 = $this->provider->create($share1);
2812
+        $share1 = $provider->acceptShare($share1, $u2->getUid());
2813
+
2814
+        $share2 = $shareManager->newShare();
2815
+        $share2->setNode($folder2)
2816
+            ->setSharedBy($u2->getUID())
2817
+            ->setSharedWith($g1->getGID())
2818
+            ->setShareOwner($u1->getUID())
2819
+            ->setShareType(IShare::TYPE_GROUP)
2820
+            ->setPermissions(Constants::PERMISSION_ALL);
2821
+        $share2 = $this->provider->create($share2);
2822
+        $share2 = $provider->acceptShare($share2, $u3->getUid());
2823
+        $share2 = $provider->acceptShare($share2, $u4->getUid());
2824
+
2825
+        $shareManager->deleteFromSelf($share2, $u4->getUID());
2826
+
2827
+        $share3 = $shareManager->newShare();
2828
+        $share3->setNode($file1)
2829
+            ->setSharedBy($u3->getUID())
2830
+            ->setShareOwner($u1->getUID())
2831
+            ->setShareType(IShare::TYPE_LINK)
2832
+            ->setPermissions(Constants::PERMISSION_READ);
2833
+        $share3 = $this->provider->create($share3);
2834
+
2835
+        $share4 = $shareManager->newShare();
2836
+        $share4->setNode($file1)
2837
+            ->setSharedBy($u3->getUID())
2838
+            ->setSharedWith($u5->getUID())
2839
+            ->setShareOwner($u1->getUID())
2840
+            ->setShareType(IShare::TYPE_USER)
2841
+            ->setPermissions(Constants::PERMISSION_READ);
2842
+        $share4 = $this->provider->create($share4);
2843
+        $share4 = $provider->acceptShare($share4, $u5->getUid());
2844
+
2845
+        $result = $provider->getAccessList([$folder1, $folder2, $file1], true);
2846
+
2847
+        $this->assertCount(3, $result['users']);
2848
+        $this->assertArrayHasKey('testShare2', $result['users']);
2849
+        $this->assertArrayHasKey('testShare3', $result['users']);
2850
+        $this->assertArrayHasKey('testShare5', $result['users']);
2851
+        $this->assertTrue($result['public']);
2852
+
2853
+        $provider->delete($share1);
2854
+        $provider->delete($share2);
2855
+        $provider->delete($share3);
2856
+        $provider->delete($share4);
2857
+
2858
+        $u1->delete();
2859
+        $u2->delete();
2860
+        $u3->delete();
2861
+        $u4->delete();
2862
+        $u5->delete();
2863
+        $g1->delete();
2864
+    }
2865
+
2866
+    public function testGetAllShares(): void {
2867
+        $qb = $this->dbConn->getQueryBuilder();
2868
+
2869
+        $qb->insert('share')
2870
+            ->values([
2871
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
2872
+                'share_with' => $qb->expr()->literal('sharedWith1'),
2873
+                'uid_owner' => $qb->expr()->literal('shareOwner1'),
2874
+                'uid_initiator' => $qb->expr()->literal('sharedBy1'),
2875
+                'item_type' => $qb->expr()->literal('file'),
2876
+                'file_source' => $qb->expr()->literal(42),
2877
+                'file_target' => $qb->expr()->literal('myTarget1'),
2878
+                'permissions' => $qb->expr()->literal(13),
2879
+            ]);
2880
+        $qb->executeStatement();
2881
+
2882
+        $id1 = $qb->getLastInsertId();
2883
+
2884
+        $qb->insert('share')
2885
+            ->values([
2886
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
2887
+                'share_with' => $qb->expr()->literal('sharedWith2'),
2888
+                'uid_owner' => $qb->expr()->literal('shareOwner2'),
2889
+                'uid_initiator' => $qb->expr()->literal('sharedBy2'),
2890
+                'item_type' => $qb->expr()->literal('file'),
2891
+                'file_source' => $qb->expr()->literal(43),
2892
+                'file_target' => $qb->expr()->literal('myTarget2'),
2893
+                'permissions' => $qb->expr()->literal(14),
2894
+            ]);
2895
+        $qb->executeStatement();
2896
+
2897
+        $id2 = $qb->getLastInsertId();
2898
+
2899
+        $qb->insert('share')
2900
+            ->values([
2901
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
2902
+                'token' => $qb->expr()->literal('token3'),
2903
+                'uid_owner' => $qb->expr()->literal('shareOwner3'),
2904
+                'uid_initiator' => $qb->expr()->literal('sharedBy3'),
2905
+                'item_type' => $qb->expr()->literal('file'),
2906
+                'file_source' => $qb->expr()->literal(44),
2907
+                'file_target' => $qb->expr()->literal('myTarget3'),
2908
+                'permissions' => $qb->expr()->literal(15),
2909
+            ]);
2910
+        $qb->executeStatement();
2911
+
2912
+        $id3 = $qb->getLastInsertId();
2913
+
2914
+        $qb->insert('share')
2915
+            ->values([
2916
+                'share_type' => $qb->expr()->literal(IShare::TYPE_EMAIL),
2917
+                'share_with' => $qb->expr()->literal('shareOwner4'),
2918
+                'token' => $qb->expr()->literal('token4'),
2919
+                'uid_owner' => $qb->expr()->literal('shareOwner4'),
2920
+                'uid_initiator' => $qb->expr()->literal('sharedBy4'),
2921
+                'item_type' => $qb->expr()->literal('file'),
2922
+                'file_source' => $qb->expr()->literal(45),
2923
+                'file_target' => $qb->expr()->literal('myTarget4'),
2924
+                'permissions' => $qb->expr()->literal(16),
2925
+            ]);
2926
+        $qb->executeStatement();
2927
+
2928
+        $id4 = $qb->getLastInsertId();
2929
+
2930
+        $qb->insert('share')
2931
+            ->values([
2932
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
2933
+                'token' => $qb->expr()->literal('token5'),
2934
+                'uid_owner' => $qb->expr()->literal('shareOwner5'),
2935
+                'uid_initiator' => $qb->expr()->literal('sharedBy5'),
2936
+                'item_type' => $qb->expr()->literal('file'),
2937
+                'file_source' => $qb->expr()->literal(46),
2938
+                'file_target' => $qb->expr()->literal('myTarget5'),
2939
+                'permissions' => $qb->expr()->literal(17),
2940
+            ]);
2941
+        $qb->executeStatement();
2942
+
2943
+        $id5 = $qb->getLastInsertId();
2944
+
2945
+        $ownerPath1 = $this->createMock(File::class);
2946
+        $shareOwner1Folder = $this->createMock(Folder::class);
2947
+        $shareOwner1Folder->method('getFirstNodeById')->willReturn($ownerPath1);
2948
+
2949
+        $ownerPath2 = $this->createMock(File::class);
2950
+        $shareOwner2Folder = $this->createMock(Folder::class);
2951
+        $shareOwner2Folder->method('getFirstNodeById')->willReturn($ownerPath2);
2952
+
2953
+        $ownerPath3 = $this->createMock(File::class);
2954
+        $shareOwner3Folder = $this->createMock(Folder::class);
2955
+        $shareOwner3Folder->method('getFirstNodeById')->willReturn($ownerPath3);
2956
+
2957
+        $ownerPath4 = $this->createMock(File::class);
2958
+        $shareOwner4Folder = $this->createMock(Folder::class);
2959
+        $shareOwner4Folder->method('getFirstNodeById')->willReturn($ownerPath4);
2960
+
2961
+        $ownerPath5 = $this->createMock(File::class);
2962
+        $shareOwner5Folder = $this->createMock(Folder::class);
2963
+        $shareOwner5Folder->method('getFirstNodeById')->willReturn($ownerPath5);
2964
+
2965
+        $this->rootFolder
2966
+            ->method('getUserFolder')
2967
+            ->willReturnMap(
2968
+                [
2969
+                    ['shareOwner1', $shareOwner1Folder],
2970
+                    ['shareOwner2', $shareOwner2Folder],
2971
+                    ['shareOwner3', $shareOwner3Folder],
2972
+                    ['shareOwner4', $shareOwner4Folder],
2973
+                    ['shareOwner5', $shareOwner5Folder],
2974
+                ]
2975
+            );
2976
+
2977
+        $shares = iterator_to_array($this->provider->getAllShares());
2978
+        $this->assertEquals(4, count($shares));
2979
+
2980
+        $share = $shares[0];
2981
+
2982
+        // We fetch the node so the root folder is eventually called
2983
+
2984
+        $this->assertEquals($id1, $share->getId());
2985
+        $this->assertEquals(IShare::TYPE_USER, $share->getShareType());
2986
+        $this->assertEquals('sharedWith1', $share->getSharedWith());
2987
+        $this->assertEquals('sharedBy1', $share->getSharedBy());
2988
+        $this->assertEquals('shareOwner1', $share->getShareOwner());
2989
+        $this->assertEquals($ownerPath1, $share->getNode());
2990
+        $this->assertEquals(13, $share->getPermissions());
2991
+        $this->assertEquals(null, $share->getToken());
2992
+        $this->assertEquals('myTarget1', $share->getTarget());
2993
+
2994
+        $share = $shares[1];
2995
+
2996
+        $this->assertEquals($id2, $share->getId());
2997
+        $this->assertEquals(IShare::TYPE_GROUP, $share->getShareType());
2998
+        $this->assertEquals('sharedWith2', $share->getSharedWith());
2999
+        $this->assertEquals('sharedBy2', $share->getSharedBy());
3000
+        $this->assertEquals('shareOwner2', $share->getShareOwner());
3001
+        $this->assertEquals($ownerPath2, $share->getNode());
3002
+        $this->assertEquals(14, $share->getPermissions());
3003
+        $this->assertEquals(null, $share->getToken());
3004
+        $this->assertEquals('myTarget2', $share->getTarget());
3005
+
3006
+        $share = $shares[2];
3007
+
3008
+        $this->assertEquals($id3, $share->getId());
3009
+        $this->assertEquals(IShare::TYPE_LINK, $share->getShareType());
3010
+        $this->assertEquals(null, $share->getSharedWith());
3011
+        $this->assertEquals('sharedBy3', $share->getSharedBy());
3012
+        $this->assertEquals('shareOwner3', $share->getShareOwner());
3013
+        $this->assertEquals($ownerPath3, $share->getNode());
3014
+        $this->assertEquals(15, $share->getPermissions());
3015
+        $this->assertEquals('token3', $share->getToken());
3016
+        $this->assertEquals('myTarget3', $share->getTarget());
3017
+
3018
+        $share = $shares[3];
3019
+
3020
+        $this->assertEquals($id5, $share->getId());
3021
+        $this->assertEquals(IShare::TYPE_LINK, $share->getShareType());
3022
+        $this->assertEquals(null, $share->getSharedWith());
3023
+        $this->assertEquals('sharedBy5', $share->getSharedBy());
3024
+        $this->assertEquals('shareOwner5', $share->getShareOwner());
3025
+        $this->assertEquals($ownerPath5, $share->getNode());
3026
+        $this->assertEquals(17, $share->getPermissions());
3027
+        $this->assertEquals('token5', $share->getToken());
3028
+        $this->assertEquals('myTarget5', $share->getTarget());
3029
+    }
3030
+
3031
+
3032
+    public function testGetSharesByPath(): void {
3033
+        $qb = $this->dbConn->getQueryBuilder();
3034
+
3035
+        $qb->insert('share')
3036
+            ->values([
3037
+                'share_type' => $qb->expr()->literal(IShare::TYPE_USER),
3038
+                'uid_owner' => $qb->expr()->literal('user1'),
3039
+                'uid_initiator' => $qb->expr()->literal('user1'),
3040
+                'share_with' => $qb->expr()->literal('user2'),
3041
+                'item_type' => $qb->expr()->literal('file'),
3042
+                'file_source' => $qb->expr()->literal(1),
3043
+            ]);
3044
+        $qb->executeStatement();
3045
+
3046
+        $id1 = $qb->getLastInsertId();
3047
+
3048
+        $qb->insert('share')
3049
+            ->values([
3050
+                'share_type' => $qb->expr()->literal(IShare::TYPE_GROUP),
3051
+                'uid_owner' => $qb->expr()->literal('user1'),
3052
+                'uid_initiator' => $qb->expr()->literal('user1'),
3053
+                'share_with' => $qb->expr()->literal('user2'),
3054
+                'item_type' => $qb->expr()->literal('file'),
3055
+                'file_source' => $qb->expr()->literal(1),
3056
+            ]);
3057
+        $qb->executeStatement();
3058
+
3059
+        $id2 = $qb->getLastInsertId();
3060
+
3061
+        $qb->insert('share')
3062
+            ->values([
3063
+                'share_type' => $qb->expr()->literal(IShare::TYPE_LINK),
3064
+                'uid_owner' => $qb->expr()->literal('user1'),
3065
+                'uid_initiator' => $qb->expr()->literal('user1'),
3066
+                'share_with' => $qb->expr()->literal('user2'),
3067
+                'item_type' => $qb->expr()->literal('file'),
3068
+                'file_source' => $qb->expr()->literal(1),
3069
+            ]);
3070
+        $qb->executeStatement();
3071
+
3072
+        $id3 = $qb->getLastInsertId();
3073
+
3074
+        $ownerPath1 = $this->createMock(File::class);
3075
+        $shareOwner1Folder = $this->createMock(Folder::class);
3076
+        $shareOwner1Folder->method('getFirstNodeById')->willReturn($ownerPath1);
3077
+
3078
+        $ownerPath2 = $this->createMock(File::class);
3079
+        $shareOwner2Folder = $this->createMock(Folder::class);
3080
+        $shareOwner2Folder->method('getFirstNodeById')->willReturn($ownerPath2);
3081
+
3082
+        $ownerPath3 = $this->createMock(File::class);
3083
+        $shareOwner3Folder = $this->createMock(Folder::class);
3084
+        $shareOwner3Folder->method('getFirstNodeById')->willReturn($ownerPath3);
3085
+
3086
+        $this->rootFolder
3087
+            ->method('getUserFolder')
3088
+            ->willReturnMap(
3089
+                [
3090
+                    ['shareOwner1', $shareOwner1Folder],
3091
+                    ['shareOwner2', $shareOwner2Folder],
3092
+                    ['shareOwner3', $shareOwner3Folder],
3093
+                ]
3094
+            );
3095
+
3096
+        $node = $this->createMock(Node::class);
3097
+        $node
3098
+            ->expects($this->once())
3099
+            ->method('getId')
3100
+            ->willReturn(1);
3101
+
3102
+        $shares = $this->provider->getSharesByPath($node);
3103
+        $this->assertCount(3, $shares);
3104
+
3105
+        $this->assertEquals($id1, $shares[0]->getId());
3106
+        $this->assertEquals(IShare::TYPE_USER, $shares[0]->getShareType());
3107
+
3108
+        $this->assertEquals($id2, $shares[1]->getId());
3109
+        $this->assertEquals(IShare::TYPE_GROUP, $shares[1]->getShareType());
3110
+
3111
+        $this->assertEquals($id3, $shares[2]->getId());
3112
+        $this->assertEquals(IShare::TYPE_LINK, $shares[2]->getShareType());
3113
+    }
3114 3114
 }
Please login to merge, or discard this patch.
tests/lib/Share20/ManagerTest.php 1 patch
Indentation   +4759 added lines, -4759 removed lines patch added patch discarded remove patch
@@ -64,10 +64,10 @@  discard block
 block discarded – undo
64 64
 use Psr\Log\LoggerInterface;
65 65
 
66 66
 class DummyShareManagerListener {
67
-	public function post() {
68
-	}
69
-	public function listener() {
70
-	}
67
+    public function post() {
68
+    }
69
+    public function listener() {
70
+    }
71 71
 }
72 72
 
73 73
 /**
@@ -77,4950 +77,4950 @@  discard block
 block discarded – undo
77 77
  */
78 78
 #[\PHPUnit\Framework\Attributes\Group('DB')]
79 79
 class ManagerTest extends \Test\TestCase {
80
-	/** @var Manager */
81
-	protected $manager;
82
-	/** @var LoggerInterface|MockObject */
83
-	protected $logger;
84
-	/** @var IConfig|MockObject */
85
-	protected $config;
86
-	/** @var ISecureRandom|MockObject */
87
-	protected $secureRandom;
88
-	/** @var IHasher|MockObject */
89
-	protected $hasher;
90
-	/** @var IShareProvider|MockObject */
91
-	protected $defaultProvider;
92
-	/** @var IMountManager|MockObject */
93
-	protected $mountManager;
94
-	/** @var IGroupManager|MockObject */
95
-	protected $groupManager;
96
-	/** @var IL10N|MockObject */
97
-	protected $l;
98
-	/** @var IFactory|MockObject */
99
-	protected $l10nFactory;
100
-	/** @var DummyFactory */
101
-	protected $factory;
102
-	/** @var IUserManager|MockObject */
103
-	protected $userManager;
104
-	/** @var IRootFolder | MockObject */
105
-	protected $rootFolder;
106
-	/** @var IEventDispatcher|MockObject */
107
-	protected $dispatcher;
108
-	/** @var IMailer|MockObject */
109
-	protected $mailer;
110
-	/** @var IURLGenerator|MockObject */
111
-	protected $urlGenerator;
112
-	/** @var \OC_Defaults|MockObject */
113
-	protected $defaults;
114
-	/** @var IUserSession|MockObject */
115
-	protected $userSession;
116
-	/** @var KnownUserService|MockObject */
117
-	protected $knownUserService;
118
-	/** @var ShareDisableChecker|MockObject */
119
-	protected $shareDisabledChecker;
120
-	private DateTimeZone $timezone;
121
-	/** @var IDateTimeZone|MockObject */
122
-	protected $dateTimeZone;
123
-	/** @var IAppConfig|MockObject */
124
-	protected $appConfig;
125
-
126
-	protected function setUp(): void {
127
-		$this->logger = $this->createMock(LoggerInterface::class);
128
-		$this->config = $this->createMock(IConfig::class);
129
-		$this->secureRandom = $this->createMock(ISecureRandom::class);
130
-		$this->hasher = $this->createMock(IHasher::class);
131
-		$this->mountManager = $this->createMock(IMountManager::class);
132
-		$this->groupManager = $this->createMock(IGroupManager::class);
133
-		$this->userManager = $this->createMock(IUserManager::class);
134
-		$this->rootFolder = $this->createMock(IRootFolder::class);
135
-		$this->mailer = $this->createMock(IMailer::class);
136
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
137
-		$this->defaults = $this->createMock(\OC_Defaults::class);
138
-		$this->dispatcher = $this->createMock(IEventDispatcher::class);
139
-		$this->userSession = $this->createMock(IUserSession::class);
140
-		$this->knownUserService = $this->createMock(KnownUserService::class);
141
-
142
-		$this->shareDisabledChecker = new ShareDisableChecker($this->config, $this->userManager, $this->groupManager);
143
-		$this->dateTimeZone = $this->createMock(IDateTimeZone::class);
144
-		$this->timezone = new \DateTimeZone('Pacific/Auckland');
145
-		$this->dateTimeZone->method('getTimeZone')->willReturnCallback(fn () => $this->timezone);
146
-
147
-		$this->appConfig = $this->createMock(IAppConfig::class);
148
-
149
-		$this->l10nFactory = $this->createMock(IFactory::class);
150
-		$this->l = $this->createMock(IL10N::class);
151
-		$this->l->method('t')
152
-			->willReturnCallback(function ($text, $parameters = []) {
153
-				return vsprintf($text, $parameters);
154
-			});
155
-		$this->l->method('n')
156
-			->willReturnCallback(function ($singular, $plural, $count, $parameters = []) {
157
-				return vsprintf(str_replace('%n', $count, ($count === 1) ? $singular : $plural), $parameters);
158
-			});
159
-		$this->l10nFactory->method('get')->willReturn($this->l);
160
-
161
-		$this->factory = new DummyFactory(\OC::$server);
162
-
163
-		$this->manager = $this->createManager($this->factory);
164
-
165
-		$this->defaultProvider = $this->createMock(DefaultShareProvider::class);
166
-		$this->defaultProvider->method('identifier')->willReturn('default');
167
-		$this->factory->setProvider($this->defaultProvider);
168
-	}
169
-
170
-	private function createManager(IProviderFactory $factory): Manager {
171
-		return new Manager(
172
-			$this->logger,
173
-			$this->config,
174
-			$this->secureRandom,
175
-			$this->hasher,
176
-			$this->mountManager,
177
-			$this->groupManager,
178
-			$this->l10nFactory,
179
-			$factory,
180
-			$this->userManager,
181
-			$this->rootFolder,
182
-			$this->mailer,
183
-			$this->urlGenerator,
184
-			$this->defaults,
185
-			$this->dispatcher,
186
-			$this->userSession,
187
-			$this->knownUserService,
188
-			$this->shareDisabledChecker,
189
-			$this->dateTimeZone,
190
-			$this->appConfig,
191
-		);
192
-	}
193
-
194
-	/**
195
-	 * @return MockBuilder
196
-	 */
197
-	private function createManagerMock() {
198
-		return $this->getMockBuilder(Manager::class)
199
-			->setConstructorArgs([
200
-				$this->logger,
201
-				$this->config,
202
-				$this->secureRandom,
203
-				$this->hasher,
204
-				$this->mountManager,
205
-				$this->groupManager,
206
-				$this->l10nFactory,
207
-				$this->factory,
208
-				$this->userManager,
209
-				$this->rootFolder,
210
-				$this->mailer,
211
-				$this->urlGenerator,
212
-				$this->defaults,
213
-				$this->dispatcher,
214
-				$this->userSession,
215
-				$this->knownUserService,
216
-				$this->shareDisabledChecker,
217
-				$this->dateTimeZone,
218
-				$this->appConfig,
219
-			]);
220
-	}
221
-
222
-	private function createFolderMock(string $folderPath): MockObject&Folder {
223
-		$folder = $this->createMock(Folder::class);
224
-		$folder->method('getPath')->willReturn($folderPath);
225
-		$folder->method('getRelativePath')->willReturnCallback(
226
-			fn (string $path): ?string => PathHelper::getRelativePath($folderPath, $path)
227
-		);
228
-		return $folder;
229
-	}
230
-
231
-	public function testDeleteNoShareId(): void {
232
-		$this->expectException(\InvalidArgumentException::class);
233
-
234
-		$share = $this->manager->newShare();
235
-
236
-		$this->manager->deleteShare($share);
237
-	}
238
-
239
-	public static function dataTestDelete(): array {
240
-		return [
241
-			[IShare::TYPE_USER, 'sharedWithUser'],
242
-			[IShare::TYPE_GROUP, 'sharedWithGroup'],
243
-			[IShare::TYPE_LINK, ''],
244
-			[IShare::TYPE_REMOTE, '[email protected]'],
245
-		];
246
-	}
247
-
248
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataTestDelete')]
249
-	public function testDelete($shareType, $sharedWith): void {
250
-		$manager = $this->createManagerMock()
251
-			->onlyMethods(['getShareById', 'deleteChildren', 'promoteReshares'])
252
-			->getMock();
253
-
254
-		$manager->method('deleteChildren')->willReturn([]);
255
-
256
-		$path = $this->createMock(File::class);
257
-		$path->method('getId')->willReturn(1);
258
-
259
-		$share = $this->manager->newShare();
260
-		$share->setId(42)
261
-			->setProviderId('prov')
262
-			->setShareType($shareType)
263
-			->setSharedWith($sharedWith)
264
-			->setSharedBy('sharedBy')
265
-			->setNode($path)
266
-			->setTarget('myTarget');
267
-
268
-		$manager->expects($this->once())->method('deleteChildren')->with($share);
269
-		$manager->expects($this->once())->method('promoteReshares')->with($share);
270
-
271
-		$this->defaultProvider
272
-			->expects($this->once())
273
-			->method('delete')
274
-			->with($share);
275
-
276
-		$calls = [
277
-			BeforeShareDeletedEvent::class,
278
-			ShareDeletedEvent::class,
279
-		];
280
-		$this->dispatcher->expects($this->exactly(2))
281
-			->method('dispatchTyped')
282
-			->willReturnCallback(function ($event) use (&$calls, $share): void {
283
-				$expected = array_shift($calls);
284
-				$this->assertInstanceOf($expected, $event);
285
-				$this->assertEquals($share, $event->getShare());
286
-			});
287
-
288
-		$manager->deleteShare($share);
289
-	}
290
-
291
-	public function testDeleteLazyShare(): void {
292
-		$manager = $this->createManagerMock()
293
-			->onlyMethods(['getShareById', 'deleteChildren', 'promoteReshares'])
294
-			->getMock();
295
-
296
-		$manager->method('deleteChildren')->willReturn([]);
297
-
298
-		$share = $this->manager->newShare();
299
-		$share->setId(42)
300
-			->setProviderId('prov')
301
-			->setShareType(IShare::TYPE_USER)
302
-			->setSharedWith('sharedWith')
303
-			->setSharedBy('sharedBy')
304
-			->setShareOwner('shareOwner')
305
-			->setTarget('myTarget')
306
-			->setNodeId(1)
307
-			->setNodeType('file');
308
-
309
-		$this->rootFolder->expects($this->never())->method($this->anything());
310
-
311
-		$manager->expects($this->once())->method('deleteChildren')->with($share);
312
-		$manager->expects($this->once())->method('promoteReshares')->with($share);
313
-
314
-		$this->defaultProvider
315
-			->expects($this->once())
316
-			->method('delete')
317
-			->with($share);
318
-
319
-		$calls = [
320
-			BeforeShareDeletedEvent::class,
321
-			ShareDeletedEvent::class,
322
-		];
323
-		$this->dispatcher->expects($this->exactly(2))
324
-			->method('dispatchTyped')
325
-			->willReturnCallback(function ($event) use (&$calls, $share): void {
326
-				$expected = array_shift($calls);
327
-				$this->assertInstanceOf($expected, $event);
328
-				$this->assertEquals($share, $event->getShare());
329
-			});
330
-
331
-		$manager->deleteShare($share);
332
-	}
333
-
334
-	public function testDeleteNested(): void {
335
-		$manager = $this->createManagerMock()
336
-			->onlyMethods(['getShareById', 'promoteReshares'])
337
-			->getMock();
338
-
339
-		$path = $this->createMock(File::class);
340
-		$path->method('getId')->willReturn(1);
341
-
342
-		$share1 = $this->manager->newShare();
343
-		$share1->setId(42)
344
-			->setProviderId('prov')
345
-			->setShareType(IShare::TYPE_USER)
346
-			->setSharedWith('sharedWith1')
347
-			->setSharedBy('sharedBy1')
348
-			->setNode($path)
349
-			->setTarget('myTarget1');
350
-
351
-		$share2 = $this->manager->newShare();
352
-		$share2->setId(43)
353
-			->setProviderId('prov')
354
-			->setShareType(IShare::TYPE_GROUP)
355
-			->setSharedWith('sharedWith2')
356
-			->setSharedBy('sharedBy2')
357
-			->setNode($path)
358
-			->setTarget('myTarget2')
359
-			->setParent(42);
360
-
361
-		$share3 = $this->manager->newShare();
362
-		$share3->setId(44)
363
-			->setProviderId('prov')
364
-			->setShareType(IShare::TYPE_LINK)
365
-			->setSharedBy('sharedBy3')
366
-			->setNode($path)
367
-			->setTarget('myTarget3')
368
-			->setParent(43);
369
-
370
-		$this->defaultProvider
371
-			->method('getChildren')
372
-			->willReturnMap([
373
-				[$share1, [$share2]],
374
-				[$share2, [$share3]],
375
-				[$share3, []],
376
-			]);
377
-
378
-		$deleteCalls = [
379
-			$share3,
380
-			$share2,
381
-			$share1,
382
-		];
383
-		$this->defaultProvider->expects($this->exactly(3))
384
-			->method('delete')
385
-			->willReturnCallback(function ($share) use (&$deleteCalls): void {
386
-				$expected = array_shift($deleteCalls);
387
-				$this->assertEquals($expected, $share);
388
-			});
389
-
390
-		$dispatchCalls = [
391
-			[BeforeShareDeletedEvent::class, $share1],
392
-			[BeforeShareDeletedEvent::class, $share2],
393
-			[BeforeShareDeletedEvent::class, $share3],
394
-			[ShareDeletedEvent::class, $share3],
395
-			[ShareDeletedEvent::class, $share2],
396
-			[ShareDeletedEvent::class, $share1],
397
-		];
398
-		$this->dispatcher->expects($this->exactly(6))
399
-			->method('dispatchTyped')
400
-			->willReturnCallback(function ($event) use (&$dispatchCalls): void {
401
-				$expected = array_shift($dispatchCalls);
402
-				$this->assertInstanceOf($expected[0], $event);
403
-				$this->assertEquals($expected[1]->getId(), $event->getShare()->getId());
404
-			});
405
-
406
-		$manager->deleteShare($share1);
407
-	}
408
-
409
-	public function testDeleteFromSelf(): void {
410
-		$manager = $this->createManagerMock()
411
-			->onlyMethods(['getShareById'])
412
-			->getMock();
413
-
414
-		$recipientId = 'unshareFrom';
415
-		$share = $this->manager->newShare();
416
-		$share->setId(42)
417
-			->setProviderId('prov')
418
-			->setShareType(IShare::TYPE_USER)
419
-			->setSharedWith('sharedWith')
420
-			->setSharedBy('sharedBy')
421
-			->setShareOwner('shareOwner')
422
-			->setTarget('myTarget')
423
-			->setNodeId(1)
424
-			->setNodeType('file');
425
-
426
-		$this->defaultProvider
427
-			->expects($this->once())
428
-			->method('deleteFromSelf')
429
-			->with($share, $recipientId);
430
-
431
-		$this->dispatcher->expects($this->once())
432
-			->method('dispatchTyped')
433
-			->with(
434
-				$this->callBack(function (ShareDeletedFromSelfEvent $e) use ($share) {
435
-					return $e->getShare() === $share;
436
-				})
437
-			);
438
-
439
-		$manager->deleteFromSelf($share, $recipientId);
440
-	}
441
-
442
-	public function testDeleteChildren(): void {
443
-		$manager = $this->createManagerMock()
444
-			->onlyMethods(['deleteShare'])
445
-			->getMock();
446
-
447
-		$share = $this->createMock(IShare::class);
448
-		$share->method('getShareType')->willReturn(IShare::TYPE_USER);
449
-
450
-		$child1 = $this->createMock(IShare::class);
451
-		$child1->method('getShareType')->willReturn(IShare::TYPE_USER);
452
-		$child2 = $this->createMock(IShare::class);
453
-		$child2->method('getShareType')->willReturn(IShare::TYPE_USER);
454
-		$child3 = $this->createMock(IShare::class);
455
-		$child3->method('getShareType')->willReturn(IShare::TYPE_USER);
456
-
457
-		$shares = [
458
-			$child1,
459
-			$child2,
460
-			$child3,
461
-		];
462
-
463
-		$this->defaultProvider
464
-			->expects($this->exactly(4))
465
-			->method('getChildren')
466
-			->willReturnCallback(function ($_share) use ($share, $shares) {
467
-				if ($_share === $share) {
468
-					return $shares;
469
-				}
470
-				return [];
471
-			});
472
-
473
-		$calls = [
474
-			$child1,
475
-			$child2,
476
-			$child3,
477
-		];
478
-		$this->defaultProvider->expects($this->exactly(3))
479
-			->method('delete')
480
-			->willReturnCallback(function ($share) use (&$calls): void {
481
-				$expected = array_shift($calls);
482
-				$this->assertEquals($expected, $share);
483
-			});
484
-
485
-		$result = self::invokePrivate($manager, 'deleteChildren', [$share]);
486
-		$this->assertSame($shares, $result);
487
-	}
488
-
489
-	public function testPromoteReshareFile(): void {
490
-		$manager = $this->createManagerMock()
491
-			->onlyMethods(['updateShare', 'getSharesInFolder', 'generalCreateChecks'])
492
-			->getMock();
493
-
494
-		$file = $this->createMock(File::class);
495
-
496
-		$share = $this->createMock(IShare::class);
497
-		$share->method('getShareType')->willReturn(IShare::TYPE_USER);
498
-		$share->method('getNodeType')->willReturn('folder');
499
-		$share->method('getSharedWith')->willReturn('userB');
500
-		$share->method('getNode')->willReturn($file);
501
-
502
-		$reShare = $this->createMock(IShare::class);
503
-		$reShare->method('getShareType')->willReturn(IShare::TYPE_USER);
504
-		$reShare->method('getSharedBy')->willReturn('userB');
505
-		$reShare->method('getSharedWith')->willReturn('userC');
506
-		$reShare->method('getNode')->willReturn($file);
507
-
508
-		$this->defaultProvider->method('getSharesBy')
509
-			->willReturnCallback(function ($userId, $shareType, $node, $reshares, $limit, $offset) use ($reShare, $file) {
510
-				$this->assertEquals($file, $node);
511
-				if ($shareType === IShare::TYPE_USER) {
512
-					return match($userId) {
513
-						'userB' => [$reShare],
514
-					};
515
-				} else {
516
-					return [];
517
-				}
518
-			});
519
-		$manager->method('generalCreateChecks')->willThrowException(new GenericShareException());
520
-
521
-		$manager->expects($this->exactly(1))->method('updateShare')->with($reShare);
522
-
523
-		self::invokePrivate($manager, 'promoteReshares', [$share]);
524
-	}
525
-
526
-	public function testPromoteReshare(): void {
527
-		$manager = $this->createManagerMock()
528
-			->onlyMethods(['updateShare', 'getSharesInFolder', 'generalCreateChecks'])
529
-			->getMock();
530
-
531
-		$folder = $this->createFolderMock('/path/to/folder');
532
-
533
-		$subFolder = $this->createFolderMock('/path/to/folder/sub');
534
-
535
-		$otherFolder = $this->createFolderMock('/path/to/otherfolder/');
536
-
537
-		$share = $this->createMock(IShare::class);
538
-		$share->method('getShareType')->willReturn(IShare::TYPE_USER);
539
-		$share->method('getNodeType')->willReturn('folder');
540
-		$share->method('getSharedWith')->willReturn('userB');
541
-		$share->method('getNode')->willReturn($folder);
542
-
543
-		$reShare = $this->createMock(IShare::class);
544
-		$reShare->method('getShareType')->willReturn(IShare::TYPE_USER);
545
-		$reShare->method('getSharedBy')->willReturn('userB');
546
-		$reShare->method('getSharedWith')->willReturn('userC');
547
-		$reShare->method('getNode')->willReturn($folder);
548
-
549
-		$reShareInSubFolder = $this->createMock(IShare::class);
550
-		$reShareInSubFolder->method('getShareType')->willReturn(IShare::TYPE_USER);
551
-		$reShareInSubFolder->method('getSharedBy')->willReturn('userB');
552
-		$reShareInSubFolder->method('getNode')->willReturn($subFolder);
553
-
554
-		$reShareInOtherFolder = $this->createMock(IShare::class);
555
-		$reShareInOtherFolder->method('getShareType')->willReturn(IShare::TYPE_USER);
556
-		$reShareInOtherFolder->method('getSharedBy')->willReturn('userB');
557
-		$reShareInOtherFolder->method('getNode')->willReturn($otherFolder);
558
-
559
-		$this->defaultProvider->method('getSharesBy')
560
-			->willReturnCallback(function ($userId, $shareType, $node, $reshares, $limit, $offset) use ($reShare, $reShareInSubFolder, $reShareInOtherFolder) {
561
-				if ($shareType === IShare::TYPE_USER) {
562
-					return match($userId) {
563
-						'userB' => [$reShare,$reShareInSubFolder,$reShareInOtherFolder],
564
-					};
565
-				} else {
566
-					return [];
567
-				}
568
-			});
569
-		$manager->method('generalCreateChecks')->willThrowException(new GenericShareException());
570
-
571
-		$calls = [
572
-			$reShare,
573
-			$reShareInSubFolder,
574
-		];
575
-		$manager->expects($this->exactly(2))
576
-			->method('updateShare')
577
-			->willReturnCallback(function ($share) use (&$calls): void {
578
-				$expected = array_shift($calls);
579
-				$this->assertEquals($expected, $share);
580
-			});
581
-
582
-		self::invokePrivate($manager, 'promoteReshares', [$share]);
583
-	}
584
-
585
-	public function testPromoteReshareWhenUserHasAnotherShare(): void {
586
-		$manager = $this->createManagerMock()
587
-			->onlyMethods(['updateShare', 'getSharesInFolder', 'getSharedWith', 'generalCreateChecks'])
588
-			->getMock();
589
-
590
-		$folder = $this->createFolderMock('/path/to/folder');
591
-
592
-		$share = $this->createMock(IShare::class);
593
-		$share->method('getShareType')->willReturn(IShare::TYPE_USER);
594
-		$share->method('getNodeType')->willReturn('folder');
595
-		$share->method('getSharedWith')->willReturn('userB');
596
-		$share->method('getNode')->willReturn($folder);
597
-
598
-		$reShare = $this->createMock(IShare::class);
599
-		$reShare->method('getShareType')->willReturn(IShare::TYPE_USER);
600
-		$reShare->method('getNodeType')->willReturn('folder');
601
-		$reShare->method('getSharedBy')->willReturn('userB');
602
-		$reShare->method('getNode')->willReturn($folder);
603
-
604
-		$this->defaultProvider->method('getSharesBy')->willReturn([$reShare]);
605
-		$manager->method('generalCreateChecks')->willReturn(true);
606
-
607
-		/* No share is promoted because generalCreateChecks does not throw */
608
-		$manager->expects($this->never())->method('updateShare');
609
-
610
-		self::invokePrivate($manager, 'promoteReshares', [$share]);
611
-	}
612
-
613
-	public function testPromoteReshareOfUsersInGroupShare(): void {
614
-		$manager = $this->createManagerMock()
615
-			->onlyMethods(['updateShare', 'getSharesInFolder', 'getSharedWith', 'generalCreateChecks'])
616
-			->getMock();
617
-
618
-		$folder = $this->createFolderMock('/path/to/folder');
619
-
620
-		$userA = $this->createMock(IUser::class);
621
-		$userA->method('getUID')->willReturn('userA');
622
-
623
-		$share = $this->createMock(IShare::class);
624
-		$share->method('getShareType')->willReturn(IShare::TYPE_GROUP);
625
-		$share->method('getNodeType')->willReturn('folder');
626
-		$share->method('getSharedWith')->willReturn('Group');
627
-		$share->method('getNode')->willReturn($folder);
628
-		$share->method('getShareOwner')->willReturn($userA);
629
-
630
-		$reShare1 = $this->createMock(IShare::class);
631
-		$reShare1->method('getShareType')->willReturn(IShare::TYPE_USER);
632
-		$reShare1->method('getNodeType')->willReturn('folder');
633
-		$reShare1->method('getSharedBy')->willReturn('userB');
634
-		$reShare1->method('getNode')->willReturn($folder);
635
-
636
-		$reShare2 = $this->createMock(IShare::class);
637
-		$reShare2->method('getShareType')->willReturn(IShare::TYPE_USER);
638
-		$reShare2->method('getNodeType')->willReturn('folder');
639
-		$reShare2->method('getSharedBy')->willReturn('userC');
640
-		$reShare2->method('getNode')->willReturn($folder);
641
-
642
-		$userB = $this->createMock(IUser::class);
643
-		$userB->method('getUID')->willReturn('userB');
644
-		$userC = $this->createMock(IUser::class);
645
-		$userC->method('getUID')->willReturn('userC');
646
-		$group = $this->createMock(IGroup::class);
647
-		$group->method('getUsers')->willReturn([$userB, $userC]);
648
-		$this->groupManager->method('get')->with('Group')->willReturn($group);
649
-
650
-		$this->defaultProvider->method('getSharesBy')
651
-			->willReturnCallback(function ($userId, $shareType, $node, $reshares, $limit, $offset) use ($reShare1, $reShare2) {
652
-				if ($shareType === IShare::TYPE_USER) {
653
-					return match($userId) {
654
-						'userB' => [$reShare1],
655
-						'userC' => [$reShare2],
656
-					};
657
-				} else {
658
-					return [];
659
-				}
660
-			});
661
-		$manager->method('generalCreateChecks')->willThrowException(new GenericShareException());
662
-
663
-		$manager->method('getSharedWith')->willReturn([]);
664
-
665
-		$calls = [
666
-			$reShare1,
667
-			$reShare2,
668
-		];
669
-		$manager->expects($this->exactly(2))
670
-			->method('updateShare')
671
-			->willReturnCallback(function ($share) use (&$calls): void {
672
-				$expected = array_shift($calls);
673
-				$this->assertEquals($expected, $share);
674
-			});
675
-
676
-		self::invokePrivate($manager, 'promoteReshares', [$share]);
677
-	}
678
-
679
-	public function testGetShareById(): void {
680
-		$share = $this->createMock(IShare::class);
681
-
682
-		$this->defaultProvider
683
-			->expects($this->once())
684
-			->method('getShareById')
685
-			->with(42)
686
-			->willReturn($share);
687
-
688
-		$this->assertEquals($share, $this->manager->getShareById('default:42'));
689
-	}
690
-
691
-
692
-	public function testGetExpiredShareById(): void {
693
-		$this->expectException(ShareNotFound::class);
694
-
695
-		$manager = $this->createManagerMock()
696
-			->onlyMethods(['deleteShare'])
697
-			->getMock();
698
-
699
-		$date = new \DateTime();
700
-		$date->setTime(0, 0, 0);
701
-
702
-		$share = $this->manager->newShare();
703
-		$share->setExpirationDate($date)
704
-			->setShareType(IShare::TYPE_LINK);
705
-
706
-		$this->defaultProvider->expects($this->once())
707
-			->method('getShareById')
708
-			->with('42')
709
-			->willReturn($share);
710
-
711
-		$manager->expects($this->once())
712
-			->method('deleteShare')
713
-			->with($share);
714
-
715
-		$manager->getShareById('default:42');
716
-	}
717
-
718
-
719
-	public function testVerifyPasswordNullButEnforced(): void {
720
-		$this->expectException(\InvalidArgumentException::class);
721
-		$this->expectExceptionMessage('Passwords are enforced for link and mail shares');
722
-
723
-		$this->config->method('getAppValue')->willReturnMap([
724
-			['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
725
-		]);
726
-
727
-		$this->appConfig->method('getValueBool')->willReturnMap([
728
-			['core', 'shareapi_enforce_links_password', true],
729
-		]);
730
-
731
-		self::invokePrivate($this->manager, 'verifyPassword', [null]);
732
-	}
733
-
734
-	public function testVerifyPasswordNotEnforcedGroup(): void {
735
-		$this->config->method('getAppValue')->willReturnMap([
736
-			['core', 'shareapi_enforce_links_password_excluded_groups', '', '["admin"]'],
737
-			['core', 'shareapi_enforce_links_password', 'no', 'yes'],
738
-		]);
739
-
740
-		// Create admin user
741
-		$user = $this->createMock(IUser::class);
742
-		$this->userSession->method('getUser')->willReturn($user);
743
-		$this->groupManager->method('getUserGroupIds')->with($user)->willReturn(['admin']);
744
-
745
-		$result = self::invokePrivate($this->manager, 'verifyPassword', [null]);
746
-		$this->assertNull($result);
747
-	}
748
-
749
-	public function testVerifyPasswordNotEnforcedMultipleGroups(): void {
750
-		$this->config->method('getAppValue')->willReturnMap([
751
-			['core', 'shareapi_enforce_links_password_excluded_groups', '', '["admin", "special"]'],
752
-			['core', 'shareapi_enforce_links_password', 'no', 'yes'],
753
-		]);
754
-
755
-		// Create admin user
756
-		$user = $this->createMock(IUser::class);
757
-		$this->userSession->method('getUser')->willReturn($user);
758
-		$this->groupManager->method('getUserGroupIds')->with($user)->willReturn(['special']);
759
-
760
-		$result = self::invokePrivate($this->manager, 'verifyPassword', [null]);
761
-		$this->assertNull($result);
762
-	}
763
-
764
-	public function testVerifyPasswordNull(): void {
765
-		$this->config->method('getAppValue')->willReturnMap([
766
-			['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
767
-			['core', 'shareapi_enforce_links_password', 'no', 'no'],
768
-		]);
769
-
770
-		$result = self::invokePrivate($this->manager, 'verifyPassword', [null]);
771
-		$this->assertNull($result);
772
-	}
773
-
774
-	public function testVerifyPasswordHook(): void {
775
-		$this->config->method('getAppValue')->willReturnMap([
776
-			['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
777
-			['core', 'shareapi_enforce_links_password', 'no', 'no'],
778
-		]);
779
-
780
-		$this->dispatcher->expects($this->once())->method('dispatchTyped')
781
-			->willReturnCallback(function (Event $event): void {
782
-				$this->assertInstanceOf(ValidatePasswordPolicyEvent::class, $event);
783
-				/** @var ValidatePasswordPolicyEvent $event */
784
-				$this->assertSame('password', $event->getPassword());
785
-			}
786
-			);
787
-
788
-		$result = self::invokePrivate($this->manager, 'verifyPassword', ['password']);
789
-		$this->assertNull($result);
790
-	}
791
-
792
-
793
-	public function testVerifyPasswordHookFails(): void {
794
-		$this->expectException(\Exception::class);
795
-		$this->expectExceptionMessage('password not accepted');
796
-
797
-		$this->config->method('getAppValue')->willReturnMap([
798
-			['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
799
-			['core', 'shareapi_enforce_links_password', 'no', 'no'],
800
-		]);
801
-
802
-		$this->dispatcher->expects($this->once())->method('dispatchTyped')
803
-			->willReturnCallback(function (Event $event): void {
804
-				$this->assertInstanceOf(ValidatePasswordPolicyEvent::class, $event);
805
-				/** @var ValidatePasswordPolicyEvent $event */
806
-				$this->assertSame('password', $event->getPassword());
807
-				throw new HintException('password not accepted');
808
-			}
809
-			);
810
-
811
-		self::invokePrivate($this->manager, 'verifyPassword', ['password']);
812
-	}
813
-
814
-	public function createShare($id, $type, $node, $sharedWith, $sharedBy, $shareOwner,
815
-		$permissions, $expireDate = null, $password = null, $attributes = null) {
816
-		$share = $this->createMock(IShare::class);
817
-
818
-		$share->method('getShareType')->willReturn($type);
819
-		$share->method('getSharedWith')->willReturn($sharedWith);
820
-		$share->method('getSharedBy')->willReturn($sharedBy);
821
-		$share->method('getShareOwner')->willReturn($shareOwner);
822
-		$share->method('getNode')->willReturn($node);
823
-		if ($node && $node->getId()) {
824
-			$share->method('getNodeId')->willReturn($node->getId());
825
-		}
826
-		$share->method('getPermissions')->willReturn($permissions);
827
-		$share->method('getAttributes')->willReturn($attributes);
828
-		$share->method('getExpirationDate')->willReturn($expireDate);
829
-		$share->method('getPassword')->willReturn($password);
830
-
831
-		return $share;
832
-	}
833
-
834
-	public static function dataGeneralChecks(): array {
835
-		$user0 = 'user0';
836
-		$user2 = 'user1';
837
-		$group0 = 'group0';
838
-
839
-		$file = [
840
-			File::class,
841
-			[
842
-				'getId' => 108,
843
-			],
844
-			'default',
845
-		];
846
-
847
-		$node = [
848
-			Node::class,
849
-			[
850
-				'getId' => 108,
851
-			],
852
-			'default',
853
-		];
854
-
855
-		$data = [
856
-			[[null, IShare::TYPE_USER, $file, null, $user0, $user0, 31, null, null], 'Share recipient is not a valid user', true],
857
-			[[null, IShare::TYPE_USER, $file, $group0, $user0, $user0, 31, null, null], 'Share recipient is not a valid user', true],
858
-			[[null, IShare::TYPE_USER, $file, '[email protected]', $user0, $user0, 31, null, null], 'Share recipient is not a valid user', true],
859
-			[[null, IShare::TYPE_GROUP, $file, null, $user0, $user0, 31, null, null], 'Share recipient is not a valid group', true],
860
-			[[null, IShare::TYPE_GROUP, $file, $user2, $user0, $user0, 31, null, null], 'Share recipient is not a valid group', true],
861
-			[[null, IShare::TYPE_GROUP, $file, '[email protected]', $user0, $user0, 31, null, null], 'Share recipient is not a valid group', true],
862
-			[[null, IShare::TYPE_LINK, $file, $user2, $user0, $user0, 31, null, null], 'Share recipient should be empty', true],
863
-			[[null, IShare::TYPE_LINK, $file, $group0, $user0, $user0, 31, null, null], 'Share recipient should be empty', true],
864
-			[[null, IShare::TYPE_LINK, $file, '[email protected]', $user0, $user0, 31, null, null], 'Share recipient should be empty', true],
865
-			[[null, -1, $file, null, $user0, $user0, 31, null, null], 'Unknown share type', true],
866
-
867
-			[[null, IShare::TYPE_USER, $file, $user2, null, $user0, 31, null, null], 'Share initiator must be set', true],
868
-			[[null, IShare::TYPE_GROUP, $file, $group0, null, $user0, 31, null, null], 'Share initiator must be set', true],
869
-			[[null, IShare::TYPE_LINK, $file, null, null, $user0, 31, null, null], 'Share initiator must be set', true],
870
-
871
-			[[null, IShare::TYPE_USER, $file, $user0, $user0, $user0, 31, null, null], 'Cannot share with yourself', true],
872
-
873
-			[[null, IShare::TYPE_USER, null, $user2, $user0, $user0, 31, null, null], 'Shared path must be set', true],
874
-			[[null, IShare::TYPE_GROUP, null, $group0, $user0, $user0, 31, null, null], 'Shared path must be set', true],
875
-			[[null, IShare::TYPE_LINK, null, null, $user0, $user0, 31, null, null], 'Shared path must be set', true],
876
-
877
-			[[null, IShare::TYPE_USER, $node, $user2, $user0, $user0, 31, null, null], 'Shared path must be either a file or a folder', true],
878
-			[[null, IShare::TYPE_GROUP, $node, $group0, $user0, $user0, 31, null, null], 'Shared path must be either a file or a folder', true],
879
-			[[null, IShare::TYPE_LINK, $node, null, $user0, $user0, 31, null, null], 'Shared path must be either a file or a folder', true],
880
-		];
881
-
882
-		$nonShareAble = [
883
-			Folder::class,
884
-			[
885
-				'getId' => 108,
886
-				'isShareable' => false,
887
-				'getPath' => 'path',
888
-				'getName' => 'name',
889
-				'getOwner' => $user0,
890
-			],
891
-			'default',
892
-		];
893
-
894
-		$data[] = [[null, IShare::TYPE_USER, $nonShareAble, $user2, $user0, $user0, 31, null, null], 'You are not allowed to share name', true];
895
-		$data[] = [[null, IShare::TYPE_GROUP, $nonShareAble, $group0, $user0, $user0, 31, null, null], 'You are not allowed to share name', true];
896
-		$data[] = [[null, IShare::TYPE_LINK, $nonShareAble, null, $user0, $user0, 31, null, null], 'You are not allowed to share name', true];
897
-
898
-		$limitedPermssions = [
899
-			File::class,
900
-			[
901
-				'isShareable' => true,
902
-				'getPermissions' => Constants::PERMISSION_READ,
903
-				'getId' => 108,
904
-				'getPath' => 'path',
905
-				'getName' => 'name',
906
-				'getOwner' => $user0,
907
-			],
908
-			'default',
909
-		];
910
-
911
-		$data[] = [[null, IShare::TYPE_USER, $limitedPermssions, $user2, $user0, $user0, null, null, null], 'Valid permissions are required for sharing', true];
912
-		$data[] = [[null, IShare::TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, null, null, null], 'Valid permissions are required for sharing', true];
913
-		$data[] = [[null, IShare::TYPE_LINK, $limitedPermssions, null, $user0, $user0, null, null, null], 'Valid permissions are required for sharing', true];
914
-
915
-		$limitedPermssions[1]['getMountPoint'] = MoveableMount::class;
916
-
917
-		// increase permissions of a re-share
918
-		$data[] = [[null, IShare::TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, 17, null, null], 'Cannot increase permissions of path', true];
919
-		$data[] = [[null, IShare::TYPE_USER, $limitedPermssions, $user2, $user0, $user0, 3, null, null], 'Cannot increase permissions of path', true];
920
-
921
-		$nonMoveableMountPermssions = [
922
-			Folder::class,
923
-			[
924
-				'isShareable' => true,
925
-				'getPermissions' => Constants::PERMISSION_READ,
926
-				'getId' => 108,
927
-				'getPath' => 'path',
928
-				'getName' => 'name',
929
-				'getInternalPath' => '',
930
-				'getOwner' => $user0,
931
-			],
932
-			'allPermssions',
933
-		];
934
-
935
-		$data[] = [[null, IShare::TYPE_USER, $nonMoveableMountPermssions, $user2, $user0, $user0, 11, null, null], 'Cannot increase permissions of path', false];
936
-		$data[] = [[null, IShare::TYPE_GROUP, $nonMoveableMountPermssions, $group0, $user0, $user0, 11, null, null], 'Cannot increase permissions of path', false];
937
-
938
-		$rootFolder = [
939
-			Folder::class,
940
-			[
941
-				'isShareable' => true,
942
-				'getPermissions' => Constants::PERMISSION_ALL,
943
-				'getId' => 42,
944
-			],
945
-			'none',
946
-		];
947
-
948
-		$data[] = [[null, IShare::TYPE_USER, $rootFolder, $user2, $user0, $user0, 30, null, null], 'You cannot share your root folder', true];
949
-		$data[] = [[null, IShare::TYPE_GROUP, $rootFolder, $group0, $user0, $user0, 2, null, null], 'You cannot share your root folder', true];
950
-		$data[] = [[null, IShare::TYPE_LINK, $rootFolder, null, $user0, $user0, 16, null, null], 'You cannot share your root folder', true];
951
-
952
-		$allPermssionsFiles = [
953
-			File::class,
954
-			[
955
-				'isShareable' => true,
956
-				'getPermissions' => Constants::PERMISSION_ALL,
957
-				'getId' => 187,
958
-				'getOwner' => $user0,
959
-			],
960
-			'default',
961
-		];
962
-
963
-		// test invalid CREATE or DELETE permissions
964
-		$data[] = [[null, IShare::TYPE_USER, $allPermssionsFiles, $user2, $user0, $user0, Constants::PERMISSION_ALL, null, null], 'File shares cannot have create or delete permissions', true];
965
-		$data[] = [[null, IShare::TYPE_GROUP, $allPermssionsFiles, $group0, $user0, $user0, Constants::PERMISSION_READ | Constants::PERMISSION_CREATE, null, null], 'File shares cannot have create or delete permissions', true];
966
-		$data[] = [[null, IShare::TYPE_LINK, $allPermssionsFiles, null, $user0, $user0, Constants::PERMISSION_READ | Constants::PERMISSION_DELETE, null, null], 'File shares cannot have create or delete permissions', true];
967
-
968
-		$allPermssions = [
969
-			Folder::class,
970
-			[
971
-				'isShareable' => true,
972
-				'getPermissions' => Constants::PERMISSION_ALL,
973
-				'getId' => 108,
974
-				'getOwner' => $user0,
975
-			],
976
-			'default',
977
-		];
978
-
979
-		$data[] = [[null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 30, null, null], 'Shares need at least read permissions', true];
980
-		$data[] = [[null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 2, null, null], 'Shares need at least read permissions', true];
981
-
982
-		// test invalid permissions
983
-		$data[] = [[null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 32, null, null], 'Valid permissions are required for sharing', true];
984
-		$data[] = [[null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 63, null, null], 'Valid permissions are required for sharing', true];
985
-		$data[] = [[null, IShare::TYPE_LINK, $allPermssions, null, $user0, $user0, -1, null, null], 'Valid permissions are required for sharing', true];
986
-
987
-		// working shares
988
-		$data[] = [[null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 31, null, null], null, false];
989
-		$data[] = [[null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 3, null, null], null, false];
990
-		$data[] = [[null, IShare::TYPE_LINK, $allPermssions, null, $user0, $user0, 17, null, null], null, false];
991
-
992
-		$remoteFile = [
993
-			Folder::class,
994
-			[
995
-				'isShareable' => true,
996
-				'getPermissions' => Constants::PERMISSION_READ ^ Constants::PERMISSION_UPDATE,
997
-				'getId' => 108,
998
-				'getOwner' => $user0,
999
-			],
1000
-			'remote',
1001
-		];
1002
-
1003
-		$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 1, null, null], null, false];
1004
-		$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 3, null, null], null, false];
1005
-		$data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 31, null, null], 'Cannot increase permissions of ', true];
1006
-
1007
-		return $data;
1008
-	}
1009
-
1010
-	private function createNodeMock(string $class, array $methods, string $storageType): MockObject {
1011
-		$mock = $this->createMock($class);
1012
-		foreach ($methods as $methodName => $return) {
1013
-			if ($methodName === 'getOwner') {
1014
-				$uid = $return;
1015
-				$return = $this->createMock(IUser::class);
1016
-				$return->method('getUID')
1017
-					->willReturn($uid);
1018
-			} elseif ($methodName === 'getMountPoint') {
1019
-				$return = $this->createMock($return);
1020
-			}
1021
-			$mock->method($methodName)->willReturn($return);
1022
-		}
1023
-		switch ($storageType) {
1024
-			case 'default':
1025
-				$storage = $this->createMock(IStorage::class);
1026
-				$storage->method('instanceOfStorage')
1027
-					->with('\OCA\Files_Sharing\External\Storage')
1028
-					->willReturn(false);
1029
-				break;
1030
-			case 'allPermssions':
1031
-				$storage = $this->createMock(IStorage::class);
1032
-				$storage->method('instanceOfStorage')
1033
-					->with('\OCA\Files_Sharing\External\Storage')
1034
-					->willReturn(false);
1035
-				$storage->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
1036
-				break;
1037
-			case 'none':
1038
-				$storage = false;
1039
-				break;
1040
-			case 'remote':
1041
-				$storage = $this->createMock(IStorage::class);
1042
-				$storage->method('instanceOfStorage')
1043
-					->with('\OCA\Files_Sharing\External\Storage')
1044
-					->willReturn(true);
1045
-				break;
1046
-			default:
1047
-				throw new \Exception('Unknown storage type ' . $storageType);
1048
-		}
1049
-		if ($storage === false) {
1050
-			$mock->expects(self::never())->method('getStorage');
1051
-		} else {
1052
-			$mock->method('getStorage')
1053
-				->willReturn($storage);
1054
-		}
1055
-
1056
-		return $mock;
1057
-	}
1058
-
1059
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataGeneralChecks')]
1060
-	public function testGeneralChecks(array $shareParams, ?string $exceptionMessage, bool $exception): void {
1061
-		if ($shareParams[2] !== null) {
1062
-			$shareParams[2] = $this->createNodeMock(...$shareParams[2]);
1063
-		}
1064
-		$share = $this->createShare(...$shareParams);
1065
-
1066
-		$thrown = null;
1067
-
1068
-		$this->userManager->method('userExists')->willReturnMap([
1069
-			['user0', true],
1070
-			['user1', true],
1071
-		]);
1072
-
1073
-		$this->groupManager->method('groupExists')->willReturnMap([
1074
-			['group0', true],
1075
-		]);
1076
-
1077
-		$userFolder = $this->createMock(Folder::class);
1078
-		$userFolder->expects($this->any())
1079
-			->method('getId')
1080
-			->willReturn(42);
1081
-		// Id 108 is used in the data to refer to the node of the share.
1082
-		$userFolder->method('getById')
1083
-			->with(108)
1084
-			->willReturn([$share->getNode()]);
1085
-		$userFolder->expects($this->any())
1086
-			->method('getRelativePath')
1087
-			->willReturnArgument(0);
1088
-		$this->rootFolder->method('getUserFolder')->willReturn($userFolder);
1089
-
1090
-
1091
-		try {
1092
-			self::invokePrivate($this->manager, 'generalCreateChecks', [$share]);
1093
-			$thrown = false;
1094
-		} catch (GenericShareException $e) {
1095
-			$this->assertEquals($exceptionMessage, $e->getHint());
1096
-			$thrown = true;
1097
-		} catch (\InvalidArgumentException $e) {
1098
-			$this->assertEquals($exceptionMessage, $e->getMessage());
1099
-			$thrown = true;
1100
-		}
1101
-
1102
-		$this->assertSame($exception, $thrown);
1103
-	}
1104
-
1105
-
1106
-	public function testGeneralCheckShareRoot(): void {
1107
-		$this->expectException(\InvalidArgumentException::class);
1108
-		$this->expectExceptionMessage('You cannot share your root folder');
1109
-
1110
-		$thrown = null;
1111
-
1112
-		$this->userManager->method('userExists')->willReturnMap([
1113
-			['user0', true],
1114
-			['user1', true],
1115
-		]);
1116
-
1117
-		$userFolder = $this->createMock(Folder::class);
1118
-		$userFolder->method('isSubNode')->with($userFolder)->willReturn(false);
1119
-		$this->rootFolder->method('getUserFolder')->willReturn($userFolder);
1120
-
1121
-		$share = $this->manager->newShare();
1122
-
1123
-		$share->setShareType(IShare::TYPE_USER)
1124
-			->setSharedWith('user0')
1125
-			->setSharedBy('user1')
1126
-			->setNode($userFolder);
1127
-
1128
-		self::invokePrivate($this->manager, 'generalCreateChecks', [$share]);
1129
-	}
1130
-
1131
-	public static function validateExpirationDateInternalProvider() {
1132
-		return [[IShare::TYPE_USER], [IShare::TYPE_REMOTE], [IShare::TYPE_REMOTE_GROUP]];
1133
-	}
1134
-
1135
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1136
-	public function testValidateExpirationDateInternalInPast($shareType): void {
1137
-		$this->expectException(GenericShareException::class);
1138
-		$this->expectExceptionMessage('Expiration date is in the past');
1139
-
1140
-		// Expire date in the past
1141
-		$past = new \DateTime();
1142
-		$past->sub(new \DateInterval('P1D'));
1143
-
1144
-		$share = $this->manager->newShare();
1145
-		$share->setShareType($shareType);
1146
-		$share->setExpirationDate($past);
1147
-
1148
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1149
-	}
1150
-
1151
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1152
-	public function testValidateExpirationDateInternalEnforceButNotSet($shareType): void {
1153
-		$this->expectException(\InvalidArgumentException::class);
1154
-		$this->expectExceptionMessage('Expiration date is enforced');
1155
-
1156
-		$share = $this->manager->newShare();
1157
-		$share->setProviderId('foo')->setId('bar');
1158
-		$share->setShareType($shareType);
1159
-		if ($shareType === IShare::TYPE_USER) {
1160
-			$this->config->method('getAppValue')
1161
-				->willReturnMap([
1162
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1163
-					['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1164
-				]);
1165
-		} else {
1166
-			$this->config->method('getAppValue')
1167
-				->willReturnMap([
1168
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1169
-					['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1170
-				]);
1171
-		}
1172
-
1173
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1174
-	}
1175
-
1176
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1177
-	public function testValidateExpirationDateInternalEnforceButNotEnabledAndNotSet($shareType): void {
1178
-		$share = $this->manager->newShare();
1179
-		$share->setProviderId('foo')->setId('bar');
1180
-		$share->setShareType($shareType);
1181
-
1182
-		if ($shareType === IShare::TYPE_USER) {
1183
-			$this->config->method('getAppValue')
1184
-				->willReturnMap([
1185
-					['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1186
-				]);
1187
-		} else {
1188
-			$this->config->method('getAppValue')
1189
-				->willReturnMap([
1190
-					['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1191
-				]);
1192
-		}
1193
-
1194
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1195
-
1196
-		$this->assertNull($share->getExpirationDate());
1197
-	}
1198
-
1199
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1200
-	public function testValidateExpirationDateInternalEnforceButNotSetNewShare($shareType): void {
1201
-		$share = $this->manager->newShare();
1202
-		$share->setShareType($shareType);
1203
-
1204
-		if ($shareType === IShare::TYPE_USER) {
1205
-			$this->config->method('getAppValue')
1206
-				->willReturnMap([
1207
-					['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1208
-					['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1209
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1210
-					['core', 'internal_defaultExpDays', '3', '3'],
1211
-				]);
1212
-		} else {
1213
-			$this->config->method('getAppValue')
1214
-				->willReturnMap([
1215
-					['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1216
-					['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1217
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1218
-					['core', 'remote_defaultExpDays', '3', '3'],
1219
-				]);
1220
-		}
1221
-
1222
-		$expected = new \DateTime('now', $this->timezone);
1223
-		$expected->setTime(0, 0, 0);
1224
-		$expected->add(new \DateInterval('P3D'));
1225
-
1226
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1227
-
1228
-		$this->assertNotNull($share->getExpirationDate());
1229
-		$this->assertEquals($expected, $share->getExpirationDate());
1230
-	}
1231
-
1232
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1233
-	public function testValidateExpirationDateInternalEnforceRelaxedDefaultButNotSetNewShare($shareType): void {
1234
-		$share = $this->manager->newShare();
1235
-		$share->setShareType($shareType);
1236
-
1237
-		if ($shareType === IShare::TYPE_USER) {
1238
-			$this->config->method('getAppValue')
1239
-				->willReturnMap([
1240
-					['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1241
-					['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1242
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1243
-					['core', 'internal_defaultExpDays', '3', '1'],
1244
-				]);
1245
-		} else {
1246
-			$this->config->method('getAppValue')
1247
-				->willReturnMap([
1248
-					['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1249
-					['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1250
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1251
-					['core', 'remote_defaultExpDays', '3', '1'],
1252
-				]);
1253
-		}
1254
-
1255
-		$expected = new \DateTime('now', $this->timezone);
1256
-		$expected->setTime(0, 0, 0);
1257
-		$expected->add(new \DateInterval('P1D'));
1258
-
1259
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1260
-
1261
-		$this->assertNotNull($share->getExpirationDate());
1262
-		$this->assertEquals($expected, $share->getExpirationDate());
1263
-	}
1264
-
1265
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1266
-	public function testValidateExpirationDateInternalEnforceTooFarIntoFuture($shareType): void {
1267
-		$this->expectException(GenericShareException::class);
1268
-		$this->expectExceptionMessage('Cannot set expiration date more than 3 days in the future');
1269
-
1270
-		$future = new \DateTime();
1271
-		$future->add(new \DateInterval('P7D'));
1272
-
1273
-		$share = $this->manager->newShare();
1274
-		$share->setShareType($shareType);
1275
-		$share->setExpirationDate($future);
1276
-
1277
-		if ($shareType === IShare::TYPE_USER) {
1278
-			$this->config->method('getAppValue')
1279
-				->willReturnMap([
1280
-					['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1281
-					['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1282
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1283
-				]);
1284
-		} else {
1285
-			$this->config->method('getAppValue')
1286
-				->willReturnMap([
1287
-					['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1288
-					['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1289
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1290
-				]);
1291
-		}
1292
-
1293
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1294
-	}
1295
-
1296
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1297
-	public function testValidateExpirationDateInternalEnforceValid($shareType): void {
1298
-		$future = new \DateTime('now', $this->dateTimeZone->getTimeZone());
1299
-		$future->add(new \DateInterval('P2D'));
1300
-		$future->setTime(1, 2, 3);
1301
-
1302
-		$expected = clone $future;
1303
-		$expected->setTime(0, 0, 0);
1304
-
1305
-		$share = $this->manager->newShare();
1306
-		$share->setShareType($shareType);
1307
-		$share->setExpirationDate($future);
1308
-
1309
-		if ($shareType === IShare::TYPE_USER) {
1310
-			$this->config->method('getAppValue')
1311
-				->willReturnMap([
1312
-					['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1313
-					['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1314
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1315
-				]);
1316
-		} else {
1317
-			$this->config->method('getAppValue')
1318
-				->willReturnMap([
1319
-					['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1320
-					['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1321
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1322
-				]);
1323
-		}
1324
-
1325
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1326
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1327
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($future) {
1328
-			return $data['expirationDate'] == $future;
1329
-		}));
1330
-
1331
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1332
-
1333
-		$this->assertEquals($expected, $share->getExpirationDate());
1334
-	}
1335
-
1336
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1337
-	public function testValidateExpirationDateInternalNoDefault($shareType): void {
1338
-		$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
1339
-		$date->add(new \DateInterval('P5D'));
1340
-		$date->setTime(1, 2, 3);
1341
-
1342
-		$expected = clone $date;
1343
-		$expected->setTime(0, 0, 0);
1344
-
1345
-		$share = $this->manager->newShare();
1346
-		$share->setShareType($shareType);
1347
-		$share->setExpirationDate($date);
1348
-
1349
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1350
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1351
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1352
-			return $data['expirationDate'] == $expected && $data['passwordSet'] === false;
1353
-		}));
1354
-
1355
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1356
-
1357
-		$this->assertEquals($expected, $share->getExpirationDate());
1358
-	}
1359
-
1360
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1361
-	public function testValidateExpirationDateInternalNoDateNoDefault($shareType): void {
1362
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1363
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1364
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) {
1365
-			return $data['expirationDate'] === null && $data['passwordSet'] === true;
1366
-		}));
1367
-
1368
-		$share = $this->manager->newShare();
1369
-		$share->setShareType($shareType);
1370
-		$share->setPassword('password');
1371
-
1372
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1373
-
1374
-		$this->assertNull($share->getExpirationDate());
1375
-	}
1376
-
1377
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1378
-	public function testValidateExpirationDateInternalNoDateDefault($shareType): void {
1379
-		$share = $this->manager->newShare();
1380
-		$share->setShareType($shareType);
1381
-
1382
-		$expected = new \DateTime('now', $this->timezone);
1383
-		$expected->setTime(0, 0);
1384
-		$expected->add(new \DateInterval('P3D'));
1385
-		$expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1386
-
1387
-		if ($shareType === IShare::TYPE_USER) {
1388
-			$this->config->method('getAppValue')
1389
-				->willReturnMap([
1390
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1391
-					['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1392
-					['core', 'internal_defaultExpDays', '3', '3'],
1393
-				]);
1394
-		} else {
1395
-			$this->config->method('getAppValue')
1396
-				->willReturnMap([
1397
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1398
-					['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1399
-					['core', 'remote_defaultExpDays', '3', '3'],
1400
-				]);
1401
-		}
1402
-
1403
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1404
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1405
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1406
-			return $data['expirationDate'] == $expected;
1407
-		}));
1408
-
1409
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1410
-
1411
-		$this->assertEquals($expected, $share->getExpirationDate());
1412
-	}
1413
-
1414
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1415
-	public function testValidateExpirationDateInternalDefault($shareType): void {
1416
-		$future = new \DateTime('now', $this->timezone);
1417
-		$future->add(new \DateInterval('P5D'));
1418
-		$future->setTime(1, 2, 3);
1419
-
1420
-		$expected = clone $future;
1421
-		$expected->setTime(0, 0);
1422
-
1423
-		$share = $this->manager->newShare();
1424
-		$share->setShareType($shareType);
1425
-		$share->setExpirationDate($future);
1426
-
1427
-		if ($shareType === IShare::TYPE_USER) {
1428
-			$this->config->method('getAppValue')
1429
-				->willReturnMap([
1430
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1431
-					['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1432
-					['core', 'internal_defaultExpDays', '3', '1'],
1433
-				]);
1434
-		} else {
1435
-			$this->config->method('getAppValue')
1436
-				->willReturnMap([
1437
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1438
-					['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1439
-					['core', 'remote_defaultExpDays', '3', '1'],
1440
-				]);
1441
-		}
1442
-
1443
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1444
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1445
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1446
-			return $data['expirationDate'] == $expected;
1447
-		}));
1448
-
1449
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1450
-
1451
-		$this->assertEquals($expected, $share->getExpirationDate());
1452
-	}
1453
-
1454
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1455
-	public function testValidateExpirationDateInternalHookModification($shareType): void {
1456
-		$nextWeek = new \DateTime('now', $this->timezone);
1457
-		$nextWeek->add(new \DateInterval('P7D'));
1458
-		$nextWeek->setTime(0, 0, 0);
1459
-
1460
-		$save = clone $nextWeek;
1461
-
1462
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1463
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1464
-		$hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1465
-			$data['expirationDate']->sub(new \DateInterval('P2D'));
1466
-		});
1467
-
1468
-		$share = $this->manager->newShare();
1469
-		$share->setShareType($shareType);
1470
-		$share->setExpirationDate($nextWeek);
1471
-
1472
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1473
-
1474
-		$save->sub(new \DateInterval('P2D'));
1475
-		$this->assertEquals($save, $share->getExpirationDate());
1476
-	}
1477
-
1478
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1479
-	public function testValidateExpirationDateInternalHookException($shareType): void {
1480
-		$this->expectException(\Exception::class);
1481
-		$this->expectExceptionMessage('Invalid date!');
1482
-
1483
-		$nextWeek = new \DateTime();
1484
-		$nextWeek->add(new \DateInterval('P7D'));
1485
-		$nextWeek->setTime(0, 0, 0);
1486
-
1487
-		$share = $this->manager->newShare();
1488
-		$share->setShareType($shareType);
1489
-		$share->setExpirationDate($nextWeek);
1490
-
1491
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1492
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1493
-		$hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1494
-			$data['accepted'] = false;
1495
-			$data['message'] = 'Invalid date!';
1496
-		});
1497
-
1498
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1499
-	}
1500
-
1501
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1502
-	public function testValidateExpirationDateInternalExistingShareNoDefault($shareType): void {
1503
-		$share = $this->manager->newShare();
1504
-		$share->setShareType($shareType);
1505
-		$share->setId('42')->setProviderId('foo');
1506
-
1507
-		if ($shareType === IShare::TYPE_USER) {
1508
-			$this->config->method('getAppValue')
1509
-				->willReturnMap([
1510
-					['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1511
-					['core', 'shareapi_internal_expire_after_n_days', '7', '6'],
1512
-				]);
1513
-		} else {
1514
-			$this->config->method('getAppValue')
1515
-				->willReturnMap([
1516
-					['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1517
-					['core', 'shareapi_remote_expire_after_n_days', '7', '6'],
1518
-				]);
1519
-		}
1520
-
1521
-		self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1522
-
1523
-		$this->assertEquals(null, $share->getExpirationDate());
1524
-	}
1525
-
1526
-	public function testValidateExpirationDateInPast(): void {
1527
-		$this->expectException(GenericShareException::class);
1528
-		$this->expectExceptionMessage('Expiration date is in the past');
1529
-
1530
-		// Expire date in the past
1531
-		$past = new \DateTime();
1532
-		$past->sub(new \DateInterval('P1D'));
1533
-
1534
-		$share = $this->manager->newShare();
1535
-		$share->setExpirationDate($past);
1536
-
1537
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1538
-	}
1539
-
1540
-	public function testValidateExpirationDateEnforceButNotSet(): void {
1541
-		$this->expectException(\InvalidArgumentException::class);
1542
-		$this->expectExceptionMessage('Expiration date is enforced');
1543
-
1544
-		$share = $this->manager->newShare();
1545
-		$share->setProviderId('foo')->setId('bar');
1546
-
1547
-		$this->appConfig->method('getValueBool')
1548
-			->willReturnMap([
1549
-				['core', 'shareapi_default_expire_date', true],
1550
-				['core', 'shareapi_enforce_expire_date', true],
1551
-			]);
1552
-
1553
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1554
-	}
1555
-
1556
-	public function testValidateExpirationDateEnforceButNotEnabledAndNotSet(): void {
1557
-		$share = $this->manager->newShare();
1558
-		$share->setProviderId('foo')->setId('bar');
1559
-
1560
-		$this->config->method('getAppValue')
1561
-			->willReturnMap([
1562
-				['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
1563
-			]);
1564
-
1565
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1566
-
1567
-		$this->assertNull($share->getExpirationDate());
1568
-	}
1569
-
1570
-	public function testValidateExpirationDateEnforceButNotSetNewShare(): void {
1571
-		$share = $this->manager->newShare();
1572
-
1573
-		$this->config->method('getAppValue')
1574
-			->willReturnMap([
1575
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1576
-				['core', 'link_defaultExpDays', '3', '3'],
1577
-			]);
1578
-
1579
-		$this->appConfig->method('getValueBool')
1580
-			->willReturnMap([
1581
-				['core', 'shareapi_default_expire_date', true],
1582
-				['core', 'shareapi_enforce_expire_date', true],
1583
-			]);
1584
-
1585
-		$expected = new \DateTime('now', $this->timezone);
1586
-		$expected->setTime(0, 0, 0);
1587
-		$expected->add(new \DateInterval('P3D'));
1588
-
1589
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1590
-
1591
-		$this->assertNotNull($share->getExpirationDate());
1592
-		$this->assertEquals($expected, $share->getExpirationDate());
1593
-	}
1594
-
1595
-	public function testValidateExpirationDateEnforceRelaxedDefaultButNotSetNewShare(): void {
1596
-		$share = $this->manager->newShare();
1597
-
1598
-		$this->config->method('getAppValue')
1599
-			->willReturnMap([
1600
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1601
-				['core', 'link_defaultExpDays', '3', '1'],
1602
-			]);
1603
-
1604
-		$this->appConfig->method('getValueBool')
1605
-			->willReturnMap([
1606
-				['core', 'shareapi_default_expire_date', true],
1607
-				['core', 'shareapi_enforce_expire_date', true],
1608
-			]);
1609
-
1610
-		$expected = new \DateTime('now', $this->timezone);
1611
-		$expected->setTime(0, 0, 0);
1612
-		$expected->add(new \DateInterval('P1D'));
80
+    /** @var Manager */
81
+    protected $manager;
82
+    /** @var LoggerInterface|MockObject */
83
+    protected $logger;
84
+    /** @var IConfig|MockObject */
85
+    protected $config;
86
+    /** @var ISecureRandom|MockObject */
87
+    protected $secureRandom;
88
+    /** @var IHasher|MockObject */
89
+    protected $hasher;
90
+    /** @var IShareProvider|MockObject */
91
+    protected $defaultProvider;
92
+    /** @var IMountManager|MockObject */
93
+    protected $mountManager;
94
+    /** @var IGroupManager|MockObject */
95
+    protected $groupManager;
96
+    /** @var IL10N|MockObject */
97
+    protected $l;
98
+    /** @var IFactory|MockObject */
99
+    protected $l10nFactory;
100
+    /** @var DummyFactory */
101
+    protected $factory;
102
+    /** @var IUserManager|MockObject */
103
+    protected $userManager;
104
+    /** @var IRootFolder | MockObject */
105
+    protected $rootFolder;
106
+    /** @var IEventDispatcher|MockObject */
107
+    protected $dispatcher;
108
+    /** @var IMailer|MockObject */
109
+    protected $mailer;
110
+    /** @var IURLGenerator|MockObject */
111
+    protected $urlGenerator;
112
+    /** @var \OC_Defaults|MockObject */
113
+    protected $defaults;
114
+    /** @var IUserSession|MockObject */
115
+    protected $userSession;
116
+    /** @var KnownUserService|MockObject */
117
+    protected $knownUserService;
118
+    /** @var ShareDisableChecker|MockObject */
119
+    protected $shareDisabledChecker;
120
+    private DateTimeZone $timezone;
121
+    /** @var IDateTimeZone|MockObject */
122
+    protected $dateTimeZone;
123
+    /** @var IAppConfig|MockObject */
124
+    protected $appConfig;
125
+
126
+    protected function setUp(): void {
127
+        $this->logger = $this->createMock(LoggerInterface::class);
128
+        $this->config = $this->createMock(IConfig::class);
129
+        $this->secureRandom = $this->createMock(ISecureRandom::class);
130
+        $this->hasher = $this->createMock(IHasher::class);
131
+        $this->mountManager = $this->createMock(IMountManager::class);
132
+        $this->groupManager = $this->createMock(IGroupManager::class);
133
+        $this->userManager = $this->createMock(IUserManager::class);
134
+        $this->rootFolder = $this->createMock(IRootFolder::class);
135
+        $this->mailer = $this->createMock(IMailer::class);
136
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
137
+        $this->defaults = $this->createMock(\OC_Defaults::class);
138
+        $this->dispatcher = $this->createMock(IEventDispatcher::class);
139
+        $this->userSession = $this->createMock(IUserSession::class);
140
+        $this->knownUserService = $this->createMock(KnownUserService::class);
141
+
142
+        $this->shareDisabledChecker = new ShareDisableChecker($this->config, $this->userManager, $this->groupManager);
143
+        $this->dateTimeZone = $this->createMock(IDateTimeZone::class);
144
+        $this->timezone = new \DateTimeZone('Pacific/Auckland');
145
+        $this->dateTimeZone->method('getTimeZone')->willReturnCallback(fn () => $this->timezone);
146
+
147
+        $this->appConfig = $this->createMock(IAppConfig::class);
148
+
149
+        $this->l10nFactory = $this->createMock(IFactory::class);
150
+        $this->l = $this->createMock(IL10N::class);
151
+        $this->l->method('t')
152
+            ->willReturnCallback(function ($text, $parameters = []) {
153
+                return vsprintf($text, $parameters);
154
+            });
155
+        $this->l->method('n')
156
+            ->willReturnCallback(function ($singular, $plural, $count, $parameters = []) {
157
+                return vsprintf(str_replace('%n', $count, ($count === 1) ? $singular : $plural), $parameters);
158
+            });
159
+        $this->l10nFactory->method('get')->willReturn($this->l);
160
+
161
+        $this->factory = new DummyFactory(\OC::$server);
162
+
163
+        $this->manager = $this->createManager($this->factory);
164
+
165
+        $this->defaultProvider = $this->createMock(DefaultShareProvider::class);
166
+        $this->defaultProvider->method('identifier')->willReturn('default');
167
+        $this->factory->setProvider($this->defaultProvider);
168
+    }
169
+
170
+    private function createManager(IProviderFactory $factory): Manager {
171
+        return new Manager(
172
+            $this->logger,
173
+            $this->config,
174
+            $this->secureRandom,
175
+            $this->hasher,
176
+            $this->mountManager,
177
+            $this->groupManager,
178
+            $this->l10nFactory,
179
+            $factory,
180
+            $this->userManager,
181
+            $this->rootFolder,
182
+            $this->mailer,
183
+            $this->urlGenerator,
184
+            $this->defaults,
185
+            $this->dispatcher,
186
+            $this->userSession,
187
+            $this->knownUserService,
188
+            $this->shareDisabledChecker,
189
+            $this->dateTimeZone,
190
+            $this->appConfig,
191
+        );
192
+    }
193
+
194
+    /**
195
+     * @return MockBuilder
196
+     */
197
+    private function createManagerMock() {
198
+        return $this->getMockBuilder(Manager::class)
199
+            ->setConstructorArgs([
200
+                $this->logger,
201
+                $this->config,
202
+                $this->secureRandom,
203
+                $this->hasher,
204
+                $this->mountManager,
205
+                $this->groupManager,
206
+                $this->l10nFactory,
207
+                $this->factory,
208
+                $this->userManager,
209
+                $this->rootFolder,
210
+                $this->mailer,
211
+                $this->urlGenerator,
212
+                $this->defaults,
213
+                $this->dispatcher,
214
+                $this->userSession,
215
+                $this->knownUserService,
216
+                $this->shareDisabledChecker,
217
+                $this->dateTimeZone,
218
+                $this->appConfig,
219
+            ]);
220
+    }
221
+
222
+    private function createFolderMock(string $folderPath): MockObject&Folder {
223
+        $folder = $this->createMock(Folder::class);
224
+        $folder->method('getPath')->willReturn($folderPath);
225
+        $folder->method('getRelativePath')->willReturnCallback(
226
+            fn (string $path): ?string => PathHelper::getRelativePath($folderPath, $path)
227
+        );
228
+        return $folder;
229
+    }
230
+
231
+    public function testDeleteNoShareId(): void {
232
+        $this->expectException(\InvalidArgumentException::class);
233
+
234
+        $share = $this->manager->newShare();
235
+
236
+        $this->manager->deleteShare($share);
237
+    }
238
+
239
+    public static function dataTestDelete(): array {
240
+        return [
241
+            [IShare::TYPE_USER, 'sharedWithUser'],
242
+            [IShare::TYPE_GROUP, 'sharedWithGroup'],
243
+            [IShare::TYPE_LINK, ''],
244
+            [IShare::TYPE_REMOTE, '[email protected]'],
245
+        ];
246
+    }
247
+
248
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataTestDelete')]
249
+    public function testDelete($shareType, $sharedWith): void {
250
+        $manager = $this->createManagerMock()
251
+            ->onlyMethods(['getShareById', 'deleteChildren', 'promoteReshares'])
252
+            ->getMock();
253
+
254
+        $manager->method('deleteChildren')->willReturn([]);
255
+
256
+        $path = $this->createMock(File::class);
257
+        $path->method('getId')->willReturn(1);
258
+
259
+        $share = $this->manager->newShare();
260
+        $share->setId(42)
261
+            ->setProviderId('prov')
262
+            ->setShareType($shareType)
263
+            ->setSharedWith($sharedWith)
264
+            ->setSharedBy('sharedBy')
265
+            ->setNode($path)
266
+            ->setTarget('myTarget');
267
+
268
+        $manager->expects($this->once())->method('deleteChildren')->with($share);
269
+        $manager->expects($this->once())->method('promoteReshares')->with($share);
270
+
271
+        $this->defaultProvider
272
+            ->expects($this->once())
273
+            ->method('delete')
274
+            ->with($share);
275
+
276
+        $calls = [
277
+            BeforeShareDeletedEvent::class,
278
+            ShareDeletedEvent::class,
279
+        ];
280
+        $this->dispatcher->expects($this->exactly(2))
281
+            ->method('dispatchTyped')
282
+            ->willReturnCallback(function ($event) use (&$calls, $share): void {
283
+                $expected = array_shift($calls);
284
+                $this->assertInstanceOf($expected, $event);
285
+                $this->assertEquals($share, $event->getShare());
286
+            });
287
+
288
+        $manager->deleteShare($share);
289
+    }
290
+
291
+    public function testDeleteLazyShare(): void {
292
+        $manager = $this->createManagerMock()
293
+            ->onlyMethods(['getShareById', 'deleteChildren', 'promoteReshares'])
294
+            ->getMock();
295
+
296
+        $manager->method('deleteChildren')->willReturn([]);
297
+
298
+        $share = $this->manager->newShare();
299
+        $share->setId(42)
300
+            ->setProviderId('prov')
301
+            ->setShareType(IShare::TYPE_USER)
302
+            ->setSharedWith('sharedWith')
303
+            ->setSharedBy('sharedBy')
304
+            ->setShareOwner('shareOwner')
305
+            ->setTarget('myTarget')
306
+            ->setNodeId(1)
307
+            ->setNodeType('file');
308
+
309
+        $this->rootFolder->expects($this->never())->method($this->anything());
310
+
311
+        $manager->expects($this->once())->method('deleteChildren')->with($share);
312
+        $manager->expects($this->once())->method('promoteReshares')->with($share);
313
+
314
+        $this->defaultProvider
315
+            ->expects($this->once())
316
+            ->method('delete')
317
+            ->with($share);
318
+
319
+        $calls = [
320
+            BeforeShareDeletedEvent::class,
321
+            ShareDeletedEvent::class,
322
+        ];
323
+        $this->dispatcher->expects($this->exactly(2))
324
+            ->method('dispatchTyped')
325
+            ->willReturnCallback(function ($event) use (&$calls, $share): void {
326
+                $expected = array_shift($calls);
327
+                $this->assertInstanceOf($expected, $event);
328
+                $this->assertEquals($share, $event->getShare());
329
+            });
330
+
331
+        $manager->deleteShare($share);
332
+    }
333
+
334
+    public function testDeleteNested(): void {
335
+        $manager = $this->createManagerMock()
336
+            ->onlyMethods(['getShareById', 'promoteReshares'])
337
+            ->getMock();
338
+
339
+        $path = $this->createMock(File::class);
340
+        $path->method('getId')->willReturn(1);
341
+
342
+        $share1 = $this->manager->newShare();
343
+        $share1->setId(42)
344
+            ->setProviderId('prov')
345
+            ->setShareType(IShare::TYPE_USER)
346
+            ->setSharedWith('sharedWith1')
347
+            ->setSharedBy('sharedBy1')
348
+            ->setNode($path)
349
+            ->setTarget('myTarget1');
350
+
351
+        $share2 = $this->manager->newShare();
352
+        $share2->setId(43)
353
+            ->setProviderId('prov')
354
+            ->setShareType(IShare::TYPE_GROUP)
355
+            ->setSharedWith('sharedWith2')
356
+            ->setSharedBy('sharedBy2')
357
+            ->setNode($path)
358
+            ->setTarget('myTarget2')
359
+            ->setParent(42);
360
+
361
+        $share3 = $this->manager->newShare();
362
+        $share3->setId(44)
363
+            ->setProviderId('prov')
364
+            ->setShareType(IShare::TYPE_LINK)
365
+            ->setSharedBy('sharedBy3')
366
+            ->setNode($path)
367
+            ->setTarget('myTarget3')
368
+            ->setParent(43);
369
+
370
+        $this->defaultProvider
371
+            ->method('getChildren')
372
+            ->willReturnMap([
373
+                [$share1, [$share2]],
374
+                [$share2, [$share3]],
375
+                [$share3, []],
376
+            ]);
377
+
378
+        $deleteCalls = [
379
+            $share3,
380
+            $share2,
381
+            $share1,
382
+        ];
383
+        $this->defaultProvider->expects($this->exactly(3))
384
+            ->method('delete')
385
+            ->willReturnCallback(function ($share) use (&$deleteCalls): void {
386
+                $expected = array_shift($deleteCalls);
387
+                $this->assertEquals($expected, $share);
388
+            });
389
+
390
+        $dispatchCalls = [
391
+            [BeforeShareDeletedEvent::class, $share1],
392
+            [BeforeShareDeletedEvent::class, $share2],
393
+            [BeforeShareDeletedEvent::class, $share3],
394
+            [ShareDeletedEvent::class, $share3],
395
+            [ShareDeletedEvent::class, $share2],
396
+            [ShareDeletedEvent::class, $share1],
397
+        ];
398
+        $this->dispatcher->expects($this->exactly(6))
399
+            ->method('dispatchTyped')
400
+            ->willReturnCallback(function ($event) use (&$dispatchCalls): void {
401
+                $expected = array_shift($dispatchCalls);
402
+                $this->assertInstanceOf($expected[0], $event);
403
+                $this->assertEquals($expected[1]->getId(), $event->getShare()->getId());
404
+            });
405
+
406
+        $manager->deleteShare($share1);
407
+    }
408
+
409
+    public function testDeleteFromSelf(): void {
410
+        $manager = $this->createManagerMock()
411
+            ->onlyMethods(['getShareById'])
412
+            ->getMock();
413
+
414
+        $recipientId = 'unshareFrom';
415
+        $share = $this->manager->newShare();
416
+        $share->setId(42)
417
+            ->setProviderId('prov')
418
+            ->setShareType(IShare::TYPE_USER)
419
+            ->setSharedWith('sharedWith')
420
+            ->setSharedBy('sharedBy')
421
+            ->setShareOwner('shareOwner')
422
+            ->setTarget('myTarget')
423
+            ->setNodeId(1)
424
+            ->setNodeType('file');
425
+
426
+        $this->defaultProvider
427
+            ->expects($this->once())
428
+            ->method('deleteFromSelf')
429
+            ->with($share, $recipientId);
430
+
431
+        $this->dispatcher->expects($this->once())
432
+            ->method('dispatchTyped')
433
+            ->with(
434
+                $this->callBack(function (ShareDeletedFromSelfEvent $e) use ($share) {
435
+                    return $e->getShare() === $share;
436
+                })
437
+            );
438
+
439
+        $manager->deleteFromSelf($share, $recipientId);
440
+    }
441
+
442
+    public function testDeleteChildren(): void {
443
+        $manager = $this->createManagerMock()
444
+            ->onlyMethods(['deleteShare'])
445
+            ->getMock();
446
+
447
+        $share = $this->createMock(IShare::class);
448
+        $share->method('getShareType')->willReturn(IShare::TYPE_USER);
449
+
450
+        $child1 = $this->createMock(IShare::class);
451
+        $child1->method('getShareType')->willReturn(IShare::TYPE_USER);
452
+        $child2 = $this->createMock(IShare::class);
453
+        $child2->method('getShareType')->willReturn(IShare::TYPE_USER);
454
+        $child3 = $this->createMock(IShare::class);
455
+        $child3->method('getShareType')->willReturn(IShare::TYPE_USER);
456
+
457
+        $shares = [
458
+            $child1,
459
+            $child2,
460
+            $child3,
461
+        ];
462
+
463
+        $this->defaultProvider
464
+            ->expects($this->exactly(4))
465
+            ->method('getChildren')
466
+            ->willReturnCallback(function ($_share) use ($share, $shares) {
467
+                if ($_share === $share) {
468
+                    return $shares;
469
+                }
470
+                return [];
471
+            });
472
+
473
+        $calls = [
474
+            $child1,
475
+            $child2,
476
+            $child3,
477
+        ];
478
+        $this->defaultProvider->expects($this->exactly(3))
479
+            ->method('delete')
480
+            ->willReturnCallback(function ($share) use (&$calls): void {
481
+                $expected = array_shift($calls);
482
+                $this->assertEquals($expected, $share);
483
+            });
484
+
485
+        $result = self::invokePrivate($manager, 'deleteChildren', [$share]);
486
+        $this->assertSame($shares, $result);
487
+    }
488
+
489
+    public function testPromoteReshareFile(): void {
490
+        $manager = $this->createManagerMock()
491
+            ->onlyMethods(['updateShare', 'getSharesInFolder', 'generalCreateChecks'])
492
+            ->getMock();
493
+
494
+        $file = $this->createMock(File::class);
495
+
496
+        $share = $this->createMock(IShare::class);
497
+        $share->method('getShareType')->willReturn(IShare::TYPE_USER);
498
+        $share->method('getNodeType')->willReturn('folder');
499
+        $share->method('getSharedWith')->willReturn('userB');
500
+        $share->method('getNode')->willReturn($file);
501
+
502
+        $reShare = $this->createMock(IShare::class);
503
+        $reShare->method('getShareType')->willReturn(IShare::TYPE_USER);
504
+        $reShare->method('getSharedBy')->willReturn('userB');
505
+        $reShare->method('getSharedWith')->willReturn('userC');
506
+        $reShare->method('getNode')->willReturn($file);
507
+
508
+        $this->defaultProvider->method('getSharesBy')
509
+            ->willReturnCallback(function ($userId, $shareType, $node, $reshares, $limit, $offset) use ($reShare, $file) {
510
+                $this->assertEquals($file, $node);
511
+                if ($shareType === IShare::TYPE_USER) {
512
+                    return match($userId) {
513
+                        'userB' => [$reShare],
514
+                    };
515
+                } else {
516
+                    return [];
517
+                }
518
+            });
519
+        $manager->method('generalCreateChecks')->willThrowException(new GenericShareException());
520
+
521
+        $manager->expects($this->exactly(1))->method('updateShare')->with($reShare);
522
+
523
+        self::invokePrivate($manager, 'promoteReshares', [$share]);
524
+    }
525
+
526
+    public function testPromoteReshare(): void {
527
+        $manager = $this->createManagerMock()
528
+            ->onlyMethods(['updateShare', 'getSharesInFolder', 'generalCreateChecks'])
529
+            ->getMock();
530
+
531
+        $folder = $this->createFolderMock('/path/to/folder');
532
+
533
+        $subFolder = $this->createFolderMock('/path/to/folder/sub');
534
+
535
+        $otherFolder = $this->createFolderMock('/path/to/otherfolder/');
536
+
537
+        $share = $this->createMock(IShare::class);
538
+        $share->method('getShareType')->willReturn(IShare::TYPE_USER);
539
+        $share->method('getNodeType')->willReturn('folder');
540
+        $share->method('getSharedWith')->willReturn('userB');
541
+        $share->method('getNode')->willReturn($folder);
542
+
543
+        $reShare = $this->createMock(IShare::class);
544
+        $reShare->method('getShareType')->willReturn(IShare::TYPE_USER);
545
+        $reShare->method('getSharedBy')->willReturn('userB');
546
+        $reShare->method('getSharedWith')->willReturn('userC');
547
+        $reShare->method('getNode')->willReturn($folder);
548
+
549
+        $reShareInSubFolder = $this->createMock(IShare::class);
550
+        $reShareInSubFolder->method('getShareType')->willReturn(IShare::TYPE_USER);
551
+        $reShareInSubFolder->method('getSharedBy')->willReturn('userB');
552
+        $reShareInSubFolder->method('getNode')->willReturn($subFolder);
553
+
554
+        $reShareInOtherFolder = $this->createMock(IShare::class);
555
+        $reShareInOtherFolder->method('getShareType')->willReturn(IShare::TYPE_USER);
556
+        $reShareInOtherFolder->method('getSharedBy')->willReturn('userB');
557
+        $reShareInOtherFolder->method('getNode')->willReturn($otherFolder);
558
+
559
+        $this->defaultProvider->method('getSharesBy')
560
+            ->willReturnCallback(function ($userId, $shareType, $node, $reshares, $limit, $offset) use ($reShare, $reShareInSubFolder, $reShareInOtherFolder) {
561
+                if ($shareType === IShare::TYPE_USER) {
562
+                    return match($userId) {
563
+                        'userB' => [$reShare,$reShareInSubFolder,$reShareInOtherFolder],
564
+                    };
565
+                } else {
566
+                    return [];
567
+                }
568
+            });
569
+        $manager->method('generalCreateChecks')->willThrowException(new GenericShareException());
570
+
571
+        $calls = [
572
+            $reShare,
573
+            $reShareInSubFolder,
574
+        ];
575
+        $manager->expects($this->exactly(2))
576
+            ->method('updateShare')
577
+            ->willReturnCallback(function ($share) use (&$calls): void {
578
+                $expected = array_shift($calls);
579
+                $this->assertEquals($expected, $share);
580
+            });
581
+
582
+        self::invokePrivate($manager, 'promoteReshares', [$share]);
583
+    }
584
+
585
+    public function testPromoteReshareWhenUserHasAnotherShare(): void {
586
+        $manager = $this->createManagerMock()
587
+            ->onlyMethods(['updateShare', 'getSharesInFolder', 'getSharedWith', 'generalCreateChecks'])
588
+            ->getMock();
589
+
590
+        $folder = $this->createFolderMock('/path/to/folder');
591
+
592
+        $share = $this->createMock(IShare::class);
593
+        $share->method('getShareType')->willReturn(IShare::TYPE_USER);
594
+        $share->method('getNodeType')->willReturn('folder');
595
+        $share->method('getSharedWith')->willReturn('userB');
596
+        $share->method('getNode')->willReturn($folder);
597
+
598
+        $reShare = $this->createMock(IShare::class);
599
+        $reShare->method('getShareType')->willReturn(IShare::TYPE_USER);
600
+        $reShare->method('getNodeType')->willReturn('folder');
601
+        $reShare->method('getSharedBy')->willReturn('userB');
602
+        $reShare->method('getNode')->willReturn($folder);
603
+
604
+        $this->defaultProvider->method('getSharesBy')->willReturn([$reShare]);
605
+        $manager->method('generalCreateChecks')->willReturn(true);
606
+
607
+        /* No share is promoted because generalCreateChecks does not throw */
608
+        $manager->expects($this->never())->method('updateShare');
609
+
610
+        self::invokePrivate($manager, 'promoteReshares', [$share]);
611
+    }
612
+
613
+    public function testPromoteReshareOfUsersInGroupShare(): void {
614
+        $manager = $this->createManagerMock()
615
+            ->onlyMethods(['updateShare', 'getSharesInFolder', 'getSharedWith', 'generalCreateChecks'])
616
+            ->getMock();
617
+
618
+        $folder = $this->createFolderMock('/path/to/folder');
619
+
620
+        $userA = $this->createMock(IUser::class);
621
+        $userA->method('getUID')->willReturn('userA');
622
+
623
+        $share = $this->createMock(IShare::class);
624
+        $share->method('getShareType')->willReturn(IShare::TYPE_GROUP);
625
+        $share->method('getNodeType')->willReturn('folder');
626
+        $share->method('getSharedWith')->willReturn('Group');
627
+        $share->method('getNode')->willReturn($folder);
628
+        $share->method('getShareOwner')->willReturn($userA);
629
+
630
+        $reShare1 = $this->createMock(IShare::class);
631
+        $reShare1->method('getShareType')->willReturn(IShare::TYPE_USER);
632
+        $reShare1->method('getNodeType')->willReturn('folder');
633
+        $reShare1->method('getSharedBy')->willReturn('userB');
634
+        $reShare1->method('getNode')->willReturn($folder);
635
+
636
+        $reShare2 = $this->createMock(IShare::class);
637
+        $reShare2->method('getShareType')->willReturn(IShare::TYPE_USER);
638
+        $reShare2->method('getNodeType')->willReturn('folder');
639
+        $reShare2->method('getSharedBy')->willReturn('userC');
640
+        $reShare2->method('getNode')->willReturn($folder);
641
+
642
+        $userB = $this->createMock(IUser::class);
643
+        $userB->method('getUID')->willReturn('userB');
644
+        $userC = $this->createMock(IUser::class);
645
+        $userC->method('getUID')->willReturn('userC');
646
+        $group = $this->createMock(IGroup::class);
647
+        $group->method('getUsers')->willReturn([$userB, $userC]);
648
+        $this->groupManager->method('get')->with('Group')->willReturn($group);
649
+
650
+        $this->defaultProvider->method('getSharesBy')
651
+            ->willReturnCallback(function ($userId, $shareType, $node, $reshares, $limit, $offset) use ($reShare1, $reShare2) {
652
+                if ($shareType === IShare::TYPE_USER) {
653
+                    return match($userId) {
654
+                        'userB' => [$reShare1],
655
+                        'userC' => [$reShare2],
656
+                    };
657
+                } else {
658
+                    return [];
659
+                }
660
+            });
661
+        $manager->method('generalCreateChecks')->willThrowException(new GenericShareException());
662
+
663
+        $manager->method('getSharedWith')->willReturn([]);
664
+
665
+        $calls = [
666
+            $reShare1,
667
+            $reShare2,
668
+        ];
669
+        $manager->expects($this->exactly(2))
670
+            ->method('updateShare')
671
+            ->willReturnCallback(function ($share) use (&$calls): void {
672
+                $expected = array_shift($calls);
673
+                $this->assertEquals($expected, $share);
674
+            });
675
+
676
+        self::invokePrivate($manager, 'promoteReshares', [$share]);
677
+    }
678
+
679
+    public function testGetShareById(): void {
680
+        $share = $this->createMock(IShare::class);
681
+
682
+        $this->defaultProvider
683
+            ->expects($this->once())
684
+            ->method('getShareById')
685
+            ->with(42)
686
+            ->willReturn($share);
687
+
688
+        $this->assertEquals($share, $this->manager->getShareById('default:42'));
689
+    }
690
+
691
+
692
+    public function testGetExpiredShareById(): void {
693
+        $this->expectException(ShareNotFound::class);
694
+
695
+        $manager = $this->createManagerMock()
696
+            ->onlyMethods(['deleteShare'])
697
+            ->getMock();
698
+
699
+        $date = new \DateTime();
700
+        $date->setTime(0, 0, 0);
701
+
702
+        $share = $this->manager->newShare();
703
+        $share->setExpirationDate($date)
704
+            ->setShareType(IShare::TYPE_LINK);
705
+
706
+        $this->defaultProvider->expects($this->once())
707
+            ->method('getShareById')
708
+            ->with('42')
709
+            ->willReturn($share);
710
+
711
+        $manager->expects($this->once())
712
+            ->method('deleteShare')
713
+            ->with($share);
714
+
715
+        $manager->getShareById('default:42');
716
+    }
717
+
718
+
719
+    public function testVerifyPasswordNullButEnforced(): void {
720
+        $this->expectException(\InvalidArgumentException::class);
721
+        $this->expectExceptionMessage('Passwords are enforced for link and mail shares');
722
+
723
+        $this->config->method('getAppValue')->willReturnMap([
724
+            ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
725
+        ]);
726
+
727
+        $this->appConfig->method('getValueBool')->willReturnMap([
728
+            ['core', 'shareapi_enforce_links_password', true],
729
+        ]);
730
+
731
+        self::invokePrivate($this->manager, 'verifyPassword', [null]);
732
+    }
733
+
734
+    public function testVerifyPasswordNotEnforcedGroup(): void {
735
+        $this->config->method('getAppValue')->willReturnMap([
736
+            ['core', 'shareapi_enforce_links_password_excluded_groups', '', '["admin"]'],
737
+            ['core', 'shareapi_enforce_links_password', 'no', 'yes'],
738
+        ]);
739
+
740
+        // Create admin user
741
+        $user = $this->createMock(IUser::class);
742
+        $this->userSession->method('getUser')->willReturn($user);
743
+        $this->groupManager->method('getUserGroupIds')->with($user)->willReturn(['admin']);
744
+
745
+        $result = self::invokePrivate($this->manager, 'verifyPassword', [null]);
746
+        $this->assertNull($result);
747
+    }
748
+
749
+    public function testVerifyPasswordNotEnforcedMultipleGroups(): void {
750
+        $this->config->method('getAppValue')->willReturnMap([
751
+            ['core', 'shareapi_enforce_links_password_excluded_groups', '', '["admin", "special"]'],
752
+            ['core', 'shareapi_enforce_links_password', 'no', 'yes'],
753
+        ]);
754
+
755
+        // Create admin user
756
+        $user = $this->createMock(IUser::class);
757
+        $this->userSession->method('getUser')->willReturn($user);
758
+        $this->groupManager->method('getUserGroupIds')->with($user)->willReturn(['special']);
759
+
760
+        $result = self::invokePrivate($this->manager, 'verifyPassword', [null]);
761
+        $this->assertNull($result);
762
+    }
763
+
764
+    public function testVerifyPasswordNull(): void {
765
+        $this->config->method('getAppValue')->willReturnMap([
766
+            ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
767
+            ['core', 'shareapi_enforce_links_password', 'no', 'no'],
768
+        ]);
769
+
770
+        $result = self::invokePrivate($this->manager, 'verifyPassword', [null]);
771
+        $this->assertNull($result);
772
+    }
773
+
774
+    public function testVerifyPasswordHook(): void {
775
+        $this->config->method('getAppValue')->willReturnMap([
776
+            ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
777
+            ['core', 'shareapi_enforce_links_password', 'no', 'no'],
778
+        ]);
779
+
780
+        $this->dispatcher->expects($this->once())->method('dispatchTyped')
781
+            ->willReturnCallback(function (Event $event): void {
782
+                $this->assertInstanceOf(ValidatePasswordPolicyEvent::class, $event);
783
+                /** @var ValidatePasswordPolicyEvent $event */
784
+                $this->assertSame('password', $event->getPassword());
785
+            }
786
+            );
787
+
788
+        $result = self::invokePrivate($this->manager, 'verifyPassword', ['password']);
789
+        $this->assertNull($result);
790
+    }
791
+
792
+
793
+    public function testVerifyPasswordHookFails(): void {
794
+        $this->expectException(\Exception::class);
795
+        $this->expectExceptionMessage('password not accepted');
796
+
797
+        $this->config->method('getAppValue')->willReturnMap([
798
+            ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
799
+            ['core', 'shareapi_enforce_links_password', 'no', 'no'],
800
+        ]);
801
+
802
+        $this->dispatcher->expects($this->once())->method('dispatchTyped')
803
+            ->willReturnCallback(function (Event $event): void {
804
+                $this->assertInstanceOf(ValidatePasswordPolicyEvent::class, $event);
805
+                /** @var ValidatePasswordPolicyEvent $event */
806
+                $this->assertSame('password', $event->getPassword());
807
+                throw new HintException('password not accepted');
808
+            }
809
+            );
810
+
811
+        self::invokePrivate($this->manager, 'verifyPassword', ['password']);
812
+    }
813
+
814
+    public function createShare($id, $type, $node, $sharedWith, $sharedBy, $shareOwner,
815
+        $permissions, $expireDate = null, $password = null, $attributes = null) {
816
+        $share = $this->createMock(IShare::class);
817
+
818
+        $share->method('getShareType')->willReturn($type);
819
+        $share->method('getSharedWith')->willReturn($sharedWith);
820
+        $share->method('getSharedBy')->willReturn($sharedBy);
821
+        $share->method('getShareOwner')->willReturn($shareOwner);
822
+        $share->method('getNode')->willReturn($node);
823
+        if ($node && $node->getId()) {
824
+            $share->method('getNodeId')->willReturn($node->getId());
825
+        }
826
+        $share->method('getPermissions')->willReturn($permissions);
827
+        $share->method('getAttributes')->willReturn($attributes);
828
+        $share->method('getExpirationDate')->willReturn($expireDate);
829
+        $share->method('getPassword')->willReturn($password);
830
+
831
+        return $share;
832
+    }
833
+
834
+    public static function dataGeneralChecks(): array {
835
+        $user0 = 'user0';
836
+        $user2 = 'user1';
837
+        $group0 = 'group0';
838
+
839
+        $file = [
840
+            File::class,
841
+            [
842
+                'getId' => 108,
843
+            ],
844
+            'default',
845
+        ];
846
+
847
+        $node = [
848
+            Node::class,
849
+            [
850
+                'getId' => 108,
851
+            ],
852
+            'default',
853
+        ];
854
+
855
+        $data = [
856
+            [[null, IShare::TYPE_USER, $file, null, $user0, $user0, 31, null, null], 'Share recipient is not a valid user', true],
857
+            [[null, IShare::TYPE_USER, $file, $group0, $user0, $user0, 31, null, null], 'Share recipient is not a valid user', true],
858
+            [[null, IShare::TYPE_USER, $file, '[email protected]', $user0, $user0, 31, null, null], 'Share recipient is not a valid user', true],
859
+            [[null, IShare::TYPE_GROUP, $file, null, $user0, $user0, 31, null, null], 'Share recipient is not a valid group', true],
860
+            [[null, IShare::TYPE_GROUP, $file, $user2, $user0, $user0, 31, null, null], 'Share recipient is not a valid group', true],
861
+            [[null, IShare::TYPE_GROUP, $file, '[email protected]', $user0, $user0, 31, null, null], 'Share recipient is not a valid group', true],
862
+            [[null, IShare::TYPE_LINK, $file, $user2, $user0, $user0, 31, null, null], 'Share recipient should be empty', true],
863
+            [[null, IShare::TYPE_LINK, $file, $group0, $user0, $user0, 31, null, null], 'Share recipient should be empty', true],
864
+            [[null, IShare::TYPE_LINK, $file, '[email protected]', $user0, $user0, 31, null, null], 'Share recipient should be empty', true],
865
+            [[null, -1, $file, null, $user0, $user0, 31, null, null], 'Unknown share type', true],
866
+
867
+            [[null, IShare::TYPE_USER, $file, $user2, null, $user0, 31, null, null], 'Share initiator must be set', true],
868
+            [[null, IShare::TYPE_GROUP, $file, $group0, null, $user0, 31, null, null], 'Share initiator must be set', true],
869
+            [[null, IShare::TYPE_LINK, $file, null, null, $user0, 31, null, null], 'Share initiator must be set', true],
870
+
871
+            [[null, IShare::TYPE_USER, $file, $user0, $user0, $user0, 31, null, null], 'Cannot share with yourself', true],
872
+
873
+            [[null, IShare::TYPE_USER, null, $user2, $user0, $user0, 31, null, null], 'Shared path must be set', true],
874
+            [[null, IShare::TYPE_GROUP, null, $group0, $user0, $user0, 31, null, null], 'Shared path must be set', true],
875
+            [[null, IShare::TYPE_LINK, null, null, $user0, $user0, 31, null, null], 'Shared path must be set', true],
876
+
877
+            [[null, IShare::TYPE_USER, $node, $user2, $user0, $user0, 31, null, null], 'Shared path must be either a file or a folder', true],
878
+            [[null, IShare::TYPE_GROUP, $node, $group0, $user0, $user0, 31, null, null], 'Shared path must be either a file or a folder', true],
879
+            [[null, IShare::TYPE_LINK, $node, null, $user0, $user0, 31, null, null], 'Shared path must be either a file or a folder', true],
880
+        ];
881
+
882
+        $nonShareAble = [
883
+            Folder::class,
884
+            [
885
+                'getId' => 108,
886
+                'isShareable' => false,
887
+                'getPath' => 'path',
888
+                'getName' => 'name',
889
+                'getOwner' => $user0,
890
+            ],
891
+            'default',
892
+        ];
893
+
894
+        $data[] = [[null, IShare::TYPE_USER, $nonShareAble, $user2, $user0, $user0, 31, null, null], 'You are not allowed to share name', true];
895
+        $data[] = [[null, IShare::TYPE_GROUP, $nonShareAble, $group0, $user0, $user0, 31, null, null], 'You are not allowed to share name', true];
896
+        $data[] = [[null, IShare::TYPE_LINK, $nonShareAble, null, $user0, $user0, 31, null, null], 'You are not allowed to share name', true];
897
+
898
+        $limitedPermssions = [
899
+            File::class,
900
+            [
901
+                'isShareable' => true,
902
+                'getPermissions' => Constants::PERMISSION_READ,
903
+                'getId' => 108,
904
+                'getPath' => 'path',
905
+                'getName' => 'name',
906
+                'getOwner' => $user0,
907
+            ],
908
+            'default',
909
+        ];
910
+
911
+        $data[] = [[null, IShare::TYPE_USER, $limitedPermssions, $user2, $user0, $user0, null, null, null], 'Valid permissions are required for sharing', true];
912
+        $data[] = [[null, IShare::TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, null, null, null], 'Valid permissions are required for sharing', true];
913
+        $data[] = [[null, IShare::TYPE_LINK, $limitedPermssions, null, $user0, $user0, null, null, null], 'Valid permissions are required for sharing', true];
914
+
915
+        $limitedPermssions[1]['getMountPoint'] = MoveableMount::class;
916
+
917
+        // increase permissions of a re-share
918
+        $data[] = [[null, IShare::TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, 17, null, null], 'Cannot increase permissions of path', true];
919
+        $data[] = [[null, IShare::TYPE_USER, $limitedPermssions, $user2, $user0, $user0, 3, null, null], 'Cannot increase permissions of path', true];
920
+
921
+        $nonMoveableMountPermssions = [
922
+            Folder::class,
923
+            [
924
+                'isShareable' => true,
925
+                'getPermissions' => Constants::PERMISSION_READ,
926
+                'getId' => 108,
927
+                'getPath' => 'path',
928
+                'getName' => 'name',
929
+                'getInternalPath' => '',
930
+                'getOwner' => $user0,
931
+            ],
932
+            'allPermssions',
933
+        ];
934
+
935
+        $data[] = [[null, IShare::TYPE_USER, $nonMoveableMountPermssions, $user2, $user0, $user0, 11, null, null], 'Cannot increase permissions of path', false];
936
+        $data[] = [[null, IShare::TYPE_GROUP, $nonMoveableMountPermssions, $group0, $user0, $user0, 11, null, null], 'Cannot increase permissions of path', false];
937
+
938
+        $rootFolder = [
939
+            Folder::class,
940
+            [
941
+                'isShareable' => true,
942
+                'getPermissions' => Constants::PERMISSION_ALL,
943
+                'getId' => 42,
944
+            ],
945
+            'none',
946
+        ];
947
+
948
+        $data[] = [[null, IShare::TYPE_USER, $rootFolder, $user2, $user0, $user0, 30, null, null], 'You cannot share your root folder', true];
949
+        $data[] = [[null, IShare::TYPE_GROUP, $rootFolder, $group0, $user0, $user0, 2, null, null], 'You cannot share your root folder', true];
950
+        $data[] = [[null, IShare::TYPE_LINK, $rootFolder, null, $user0, $user0, 16, null, null], 'You cannot share your root folder', true];
951
+
952
+        $allPermssionsFiles = [
953
+            File::class,
954
+            [
955
+                'isShareable' => true,
956
+                'getPermissions' => Constants::PERMISSION_ALL,
957
+                'getId' => 187,
958
+                'getOwner' => $user0,
959
+            ],
960
+            'default',
961
+        ];
962
+
963
+        // test invalid CREATE or DELETE permissions
964
+        $data[] = [[null, IShare::TYPE_USER, $allPermssionsFiles, $user2, $user0, $user0, Constants::PERMISSION_ALL, null, null], 'File shares cannot have create or delete permissions', true];
965
+        $data[] = [[null, IShare::TYPE_GROUP, $allPermssionsFiles, $group0, $user0, $user0, Constants::PERMISSION_READ | Constants::PERMISSION_CREATE, null, null], 'File shares cannot have create or delete permissions', true];
966
+        $data[] = [[null, IShare::TYPE_LINK, $allPermssionsFiles, null, $user0, $user0, Constants::PERMISSION_READ | Constants::PERMISSION_DELETE, null, null], 'File shares cannot have create or delete permissions', true];
967
+
968
+        $allPermssions = [
969
+            Folder::class,
970
+            [
971
+                'isShareable' => true,
972
+                'getPermissions' => Constants::PERMISSION_ALL,
973
+                'getId' => 108,
974
+                'getOwner' => $user0,
975
+            ],
976
+            'default',
977
+        ];
978
+
979
+        $data[] = [[null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 30, null, null], 'Shares need at least read permissions', true];
980
+        $data[] = [[null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 2, null, null], 'Shares need at least read permissions', true];
981
+
982
+        // test invalid permissions
983
+        $data[] = [[null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 32, null, null], 'Valid permissions are required for sharing', true];
984
+        $data[] = [[null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 63, null, null], 'Valid permissions are required for sharing', true];
985
+        $data[] = [[null, IShare::TYPE_LINK, $allPermssions, null, $user0, $user0, -1, null, null], 'Valid permissions are required for sharing', true];
986
+
987
+        // working shares
988
+        $data[] = [[null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 31, null, null], null, false];
989
+        $data[] = [[null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 3, null, null], null, false];
990
+        $data[] = [[null, IShare::TYPE_LINK, $allPermssions, null, $user0, $user0, 17, null, null], null, false];
991
+
992
+        $remoteFile = [
993
+            Folder::class,
994
+            [
995
+                'isShareable' => true,
996
+                'getPermissions' => Constants::PERMISSION_READ ^ Constants::PERMISSION_UPDATE,
997
+                'getId' => 108,
998
+                'getOwner' => $user0,
999
+            ],
1000
+            'remote',
1001
+        ];
1002
+
1003
+        $data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 1, null, null], null, false];
1004
+        $data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 3, null, null], null, false];
1005
+        $data[] = [[null, IShare::TYPE_REMOTE, $remoteFile, $user2, $user0, $user0, 31, null, null], 'Cannot increase permissions of ', true];
1006
+
1007
+        return $data;
1008
+    }
1009
+
1010
+    private function createNodeMock(string $class, array $methods, string $storageType): MockObject {
1011
+        $mock = $this->createMock($class);
1012
+        foreach ($methods as $methodName => $return) {
1013
+            if ($methodName === 'getOwner') {
1014
+                $uid = $return;
1015
+                $return = $this->createMock(IUser::class);
1016
+                $return->method('getUID')
1017
+                    ->willReturn($uid);
1018
+            } elseif ($methodName === 'getMountPoint') {
1019
+                $return = $this->createMock($return);
1020
+            }
1021
+            $mock->method($methodName)->willReturn($return);
1022
+        }
1023
+        switch ($storageType) {
1024
+            case 'default':
1025
+                $storage = $this->createMock(IStorage::class);
1026
+                $storage->method('instanceOfStorage')
1027
+                    ->with('\OCA\Files_Sharing\External\Storage')
1028
+                    ->willReturn(false);
1029
+                break;
1030
+            case 'allPermssions':
1031
+                $storage = $this->createMock(IStorage::class);
1032
+                $storage->method('instanceOfStorage')
1033
+                    ->with('\OCA\Files_Sharing\External\Storage')
1034
+                    ->willReturn(false);
1035
+                $storage->method('getPermissions')->willReturn(Constants::PERMISSION_ALL);
1036
+                break;
1037
+            case 'none':
1038
+                $storage = false;
1039
+                break;
1040
+            case 'remote':
1041
+                $storage = $this->createMock(IStorage::class);
1042
+                $storage->method('instanceOfStorage')
1043
+                    ->with('\OCA\Files_Sharing\External\Storage')
1044
+                    ->willReturn(true);
1045
+                break;
1046
+            default:
1047
+                throw new \Exception('Unknown storage type ' . $storageType);
1048
+        }
1049
+        if ($storage === false) {
1050
+            $mock->expects(self::never())->method('getStorage');
1051
+        } else {
1052
+            $mock->method('getStorage')
1053
+                ->willReturn($storage);
1054
+        }
1055
+
1056
+        return $mock;
1057
+    }
1058
+
1059
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataGeneralChecks')]
1060
+    public function testGeneralChecks(array $shareParams, ?string $exceptionMessage, bool $exception): void {
1061
+        if ($shareParams[2] !== null) {
1062
+            $shareParams[2] = $this->createNodeMock(...$shareParams[2]);
1063
+        }
1064
+        $share = $this->createShare(...$shareParams);
1065
+
1066
+        $thrown = null;
1067
+
1068
+        $this->userManager->method('userExists')->willReturnMap([
1069
+            ['user0', true],
1070
+            ['user1', true],
1071
+        ]);
1072
+
1073
+        $this->groupManager->method('groupExists')->willReturnMap([
1074
+            ['group0', true],
1075
+        ]);
1076
+
1077
+        $userFolder = $this->createMock(Folder::class);
1078
+        $userFolder->expects($this->any())
1079
+            ->method('getId')
1080
+            ->willReturn(42);
1081
+        // Id 108 is used in the data to refer to the node of the share.
1082
+        $userFolder->method('getById')
1083
+            ->with(108)
1084
+            ->willReturn([$share->getNode()]);
1085
+        $userFolder->expects($this->any())
1086
+            ->method('getRelativePath')
1087
+            ->willReturnArgument(0);
1088
+        $this->rootFolder->method('getUserFolder')->willReturn($userFolder);
1089
+
1090
+
1091
+        try {
1092
+            self::invokePrivate($this->manager, 'generalCreateChecks', [$share]);
1093
+            $thrown = false;
1094
+        } catch (GenericShareException $e) {
1095
+            $this->assertEquals($exceptionMessage, $e->getHint());
1096
+            $thrown = true;
1097
+        } catch (\InvalidArgumentException $e) {
1098
+            $this->assertEquals($exceptionMessage, $e->getMessage());
1099
+            $thrown = true;
1100
+        }
1101
+
1102
+        $this->assertSame($exception, $thrown);
1103
+    }
1104
+
1105
+
1106
+    public function testGeneralCheckShareRoot(): void {
1107
+        $this->expectException(\InvalidArgumentException::class);
1108
+        $this->expectExceptionMessage('You cannot share your root folder');
1109
+
1110
+        $thrown = null;
1111
+
1112
+        $this->userManager->method('userExists')->willReturnMap([
1113
+            ['user0', true],
1114
+            ['user1', true],
1115
+        ]);
1116
+
1117
+        $userFolder = $this->createMock(Folder::class);
1118
+        $userFolder->method('isSubNode')->with($userFolder)->willReturn(false);
1119
+        $this->rootFolder->method('getUserFolder')->willReturn($userFolder);
1120
+
1121
+        $share = $this->manager->newShare();
1122
+
1123
+        $share->setShareType(IShare::TYPE_USER)
1124
+            ->setSharedWith('user0')
1125
+            ->setSharedBy('user1')
1126
+            ->setNode($userFolder);
1127
+
1128
+        self::invokePrivate($this->manager, 'generalCreateChecks', [$share]);
1129
+    }
1130
+
1131
+    public static function validateExpirationDateInternalProvider() {
1132
+        return [[IShare::TYPE_USER], [IShare::TYPE_REMOTE], [IShare::TYPE_REMOTE_GROUP]];
1133
+    }
1134
+
1135
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1136
+    public function testValidateExpirationDateInternalInPast($shareType): void {
1137
+        $this->expectException(GenericShareException::class);
1138
+        $this->expectExceptionMessage('Expiration date is in the past');
1139
+
1140
+        // Expire date in the past
1141
+        $past = new \DateTime();
1142
+        $past->sub(new \DateInterval('P1D'));
1143
+
1144
+        $share = $this->manager->newShare();
1145
+        $share->setShareType($shareType);
1146
+        $share->setExpirationDate($past);
1147
+
1148
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1149
+    }
1150
+
1151
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1152
+    public function testValidateExpirationDateInternalEnforceButNotSet($shareType): void {
1153
+        $this->expectException(\InvalidArgumentException::class);
1154
+        $this->expectExceptionMessage('Expiration date is enforced');
1155
+
1156
+        $share = $this->manager->newShare();
1157
+        $share->setProviderId('foo')->setId('bar');
1158
+        $share->setShareType($shareType);
1159
+        if ($shareType === IShare::TYPE_USER) {
1160
+            $this->config->method('getAppValue')
1161
+                ->willReturnMap([
1162
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1163
+                    ['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1164
+                ]);
1165
+        } else {
1166
+            $this->config->method('getAppValue')
1167
+                ->willReturnMap([
1168
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1169
+                    ['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1170
+                ]);
1171
+        }
1172
+
1173
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1174
+    }
1175
+
1176
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1177
+    public function testValidateExpirationDateInternalEnforceButNotEnabledAndNotSet($shareType): void {
1178
+        $share = $this->manager->newShare();
1179
+        $share->setProviderId('foo')->setId('bar');
1180
+        $share->setShareType($shareType);
1181
+
1182
+        if ($shareType === IShare::TYPE_USER) {
1183
+            $this->config->method('getAppValue')
1184
+                ->willReturnMap([
1185
+                    ['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1186
+                ]);
1187
+        } else {
1188
+            $this->config->method('getAppValue')
1189
+                ->willReturnMap([
1190
+                    ['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1191
+                ]);
1192
+        }
1193
+
1194
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1195
+
1196
+        $this->assertNull($share->getExpirationDate());
1197
+    }
1198
+
1199
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1200
+    public function testValidateExpirationDateInternalEnforceButNotSetNewShare($shareType): void {
1201
+        $share = $this->manager->newShare();
1202
+        $share->setShareType($shareType);
1203
+
1204
+        if ($shareType === IShare::TYPE_USER) {
1205
+            $this->config->method('getAppValue')
1206
+                ->willReturnMap([
1207
+                    ['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1208
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1209
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1210
+                    ['core', 'internal_defaultExpDays', '3', '3'],
1211
+                ]);
1212
+        } else {
1213
+            $this->config->method('getAppValue')
1214
+                ->willReturnMap([
1215
+                    ['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1216
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1217
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1218
+                    ['core', 'remote_defaultExpDays', '3', '3'],
1219
+                ]);
1220
+        }
1221
+
1222
+        $expected = new \DateTime('now', $this->timezone);
1223
+        $expected->setTime(0, 0, 0);
1224
+        $expected->add(new \DateInterval('P3D'));
1225
+
1226
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1227
+
1228
+        $this->assertNotNull($share->getExpirationDate());
1229
+        $this->assertEquals($expected, $share->getExpirationDate());
1230
+    }
1231
+
1232
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1233
+    public function testValidateExpirationDateInternalEnforceRelaxedDefaultButNotSetNewShare($shareType): void {
1234
+        $share = $this->manager->newShare();
1235
+        $share->setShareType($shareType);
1236
+
1237
+        if ($shareType === IShare::TYPE_USER) {
1238
+            $this->config->method('getAppValue')
1239
+                ->willReturnMap([
1240
+                    ['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1241
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1242
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1243
+                    ['core', 'internal_defaultExpDays', '3', '1'],
1244
+                ]);
1245
+        } else {
1246
+            $this->config->method('getAppValue')
1247
+                ->willReturnMap([
1248
+                    ['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1249
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1250
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1251
+                    ['core', 'remote_defaultExpDays', '3', '1'],
1252
+                ]);
1253
+        }
1254
+
1255
+        $expected = new \DateTime('now', $this->timezone);
1256
+        $expected->setTime(0, 0, 0);
1257
+        $expected->add(new \DateInterval('P1D'));
1258
+
1259
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1260
+
1261
+        $this->assertNotNull($share->getExpirationDate());
1262
+        $this->assertEquals($expected, $share->getExpirationDate());
1263
+    }
1264
+
1265
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1266
+    public function testValidateExpirationDateInternalEnforceTooFarIntoFuture($shareType): void {
1267
+        $this->expectException(GenericShareException::class);
1268
+        $this->expectExceptionMessage('Cannot set expiration date more than 3 days in the future');
1269
+
1270
+        $future = new \DateTime();
1271
+        $future->add(new \DateInterval('P7D'));
1272
+
1273
+        $share = $this->manager->newShare();
1274
+        $share->setShareType($shareType);
1275
+        $share->setExpirationDate($future);
1276
+
1277
+        if ($shareType === IShare::TYPE_USER) {
1278
+            $this->config->method('getAppValue')
1279
+                ->willReturnMap([
1280
+                    ['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1281
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1282
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1283
+                ]);
1284
+        } else {
1285
+            $this->config->method('getAppValue')
1286
+                ->willReturnMap([
1287
+                    ['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1288
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1289
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1290
+                ]);
1291
+        }
1292
+
1293
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1294
+    }
1295
+
1296
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1297
+    public function testValidateExpirationDateInternalEnforceValid($shareType): void {
1298
+        $future = new \DateTime('now', $this->dateTimeZone->getTimeZone());
1299
+        $future->add(new \DateInterval('P2D'));
1300
+        $future->setTime(1, 2, 3);
1301
+
1302
+        $expected = clone $future;
1303
+        $expected->setTime(0, 0, 0);
1304
+
1305
+        $share = $this->manager->newShare();
1306
+        $share->setShareType($shareType);
1307
+        $share->setExpirationDate($future);
1308
+
1309
+        if ($shareType === IShare::TYPE_USER) {
1310
+            $this->config->method('getAppValue')
1311
+                ->willReturnMap([
1312
+                    ['core', 'shareapi_enforce_internal_expire_date', 'no', 'yes'],
1313
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1314
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1315
+                ]);
1316
+        } else {
1317
+            $this->config->method('getAppValue')
1318
+                ->willReturnMap([
1319
+                    ['core', 'shareapi_enforce_remote_expire_date', 'no', 'yes'],
1320
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1321
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1322
+                ]);
1323
+        }
1324
+
1325
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1326
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1327
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($future) {
1328
+            return $data['expirationDate'] == $future;
1329
+        }));
1330
+
1331
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1332
+
1333
+        $this->assertEquals($expected, $share->getExpirationDate());
1334
+    }
1335
+
1336
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1337
+    public function testValidateExpirationDateInternalNoDefault($shareType): void {
1338
+        $date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
1339
+        $date->add(new \DateInterval('P5D'));
1340
+        $date->setTime(1, 2, 3);
1341
+
1342
+        $expected = clone $date;
1343
+        $expected->setTime(0, 0, 0);
1344
+
1345
+        $share = $this->manager->newShare();
1346
+        $share->setShareType($shareType);
1347
+        $share->setExpirationDate($date);
1348
+
1349
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1350
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1351
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1352
+            return $data['expirationDate'] == $expected && $data['passwordSet'] === false;
1353
+        }));
1354
+
1355
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1356
+
1357
+        $this->assertEquals($expected, $share->getExpirationDate());
1358
+    }
1359
+
1360
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1361
+    public function testValidateExpirationDateInternalNoDateNoDefault($shareType): void {
1362
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1363
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1364
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) {
1365
+            return $data['expirationDate'] === null && $data['passwordSet'] === true;
1366
+        }));
1367
+
1368
+        $share = $this->manager->newShare();
1369
+        $share->setShareType($shareType);
1370
+        $share->setPassword('password');
1371
+
1372
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1373
+
1374
+        $this->assertNull($share->getExpirationDate());
1375
+    }
1376
+
1377
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1378
+    public function testValidateExpirationDateInternalNoDateDefault($shareType): void {
1379
+        $share = $this->manager->newShare();
1380
+        $share->setShareType($shareType);
1381
+
1382
+        $expected = new \DateTime('now', $this->timezone);
1383
+        $expected->setTime(0, 0);
1384
+        $expected->add(new \DateInterval('P3D'));
1385
+        $expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1386
+
1387
+        if ($shareType === IShare::TYPE_USER) {
1388
+            $this->config->method('getAppValue')
1389
+                ->willReturnMap([
1390
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1391
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1392
+                    ['core', 'internal_defaultExpDays', '3', '3'],
1393
+                ]);
1394
+        } else {
1395
+            $this->config->method('getAppValue')
1396
+                ->willReturnMap([
1397
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1398
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1399
+                    ['core', 'remote_defaultExpDays', '3', '3'],
1400
+                ]);
1401
+        }
1402
+
1403
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1404
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1405
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1406
+            return $data['expirationDate'] == $expected;
1407
+        }));
1408
+
1409
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1410
+
1411
+        $this->assertEquals($expected, $share->getExpirationDate());
1412
+    }
1413
+
1414
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1415
+    public function testValidateExpirationDateInternalDefault($shareType): void {
1416
+        $future = new \DateTime('now', $this->timezone);
1417
+        $future->add(new \DateInterval('P5D'));
1418
+        $future->setTime(1, 2, 3);
1419
+
1420
+        $expected = clone $future;
1421
+        $expected->setTime(0, 0);
1422
+
1423
+        $share = $this->manager->newShare();
1424
+        $share->setShareType($shareType);
1425
+        $share->setExpirationDate($future);
1426
+
1427
+        if ($shareType === IShare::TYPE_USER) {
1428
+            $this->config->method('getAppValue')
1429
+                ->willReturnMap([
1430
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1431
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '3'],
1432
+                    ['core', 'internal_defaultExpDays', '3', '1'],
1433
+                ]);
1434
+        } else {
1435
+            $this->config->method('getAppValue')
1436
+                ->willReturnMap([
1437
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1438
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '3'],
1439
+                    ['core', 'remote_defaultExpDays', '3', '1'],
1440
+                ]);
1441
+        }
1442
+
1443
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1444
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1445
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1446
+            return $data['expirationDate'] == $expected;
1447
+        }));
1448
+
1449
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1450
+
1451
+        $this->assertEquals($expected, $share->getExpirationDate());
1452
+    }
1453
+
1454
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1455
+    public function testValidateExpirationDateInternalHookModification($shareType): void {
1456
+        $nextWeek = new \DateTime('now', $this->timezone);
1457
+        $nextWeek->add(new \DateInterval('P7D'));
1458
+        $nextWeek->setTime(0, 0, 0);
1459
+
1460
+        $save = clone $nextWeek;
1461
+
1462
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1463
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1464
+        $hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1465
+            $data['expirationDate']->sub(new \DateInterval('P2D'));
1466
+        });
1467
+
1468
+        $share = $this->manager->newShare();
1469
+        $share->setShareType($shareType);
1470
+        $share->setExpirationDate($nextWeek);
1471
+
1472
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1473
+
1474
+        $save->sub(new \DateInterval('P2D'));
1475
+        $this->assertEquals($save, $share->getExpirationDate());
1476
+    }
1477
+
1478
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1479
+    public function testValidateExpirationDateInternalHookException($shareType): void {
1480
+        $this->expectException(\Exception::class);
1481
+        $this->expectExceptionMessage('Invalid date!');
1482
+
1483
+        $nextWeek = new \DateTime();
1484
+        $nextWeek->add(new \DateInterval('P7D'));
1485
+        $nextWeek->setTime(0, 0, 0);
1486
+
1487
+        $share = $this->manager->newShare();
1488
+        $share->setShareType($shareType);
1489
+        $share->setExpirationDate($nextWeek);
1490
+
1491
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1492
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1493
+        $hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1494
+            $data['accepted'] = false;
1495
+            $data['message'] = 'Invalid date!';
1496
+        });
1497
+
1498
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1499
+    }
1500
+
1501
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateExpirationDateInternalProvider')]
1502
+    public function testValidateExpirationDateInternalExistingShareNoDefault($shareType): void {
1503
+        $share = $this->manager->newShare();
1504
+        $share->setShareType($shareType);
1505
+        $share->setId('42')->setProviderId('foo');
1506
+
1507
+        if ($shareType === IShare::TYPE_USER) {
1508
+            $this->config->method('getAppValue')
1509
+                ->willReturnMap([
1510
+                    ['core', 'shareapi_default_internal_expire_date', 'no', 'yes'],
1511
+                    ['core', 'shareapi_internal_expire_after_n_days', '7', '6'],
1512
+                ]);
1513
+        } else {
1514
+            $this->config->method('getAppValue')
1515
+                ->willReturnMap([
1516
+                    ['core', 'shareapi_default_remote_expire_date', 'no', 'yes'],
1517
+                    ['core', 'shareapi_remote_expire_after_n_days', '7', '6'],
1518
+                ]);
1519
+        }
1520
+
1521
+        self::invokePrivate($this->manager, 'validateExpirationDateInternal', [$share]);
1522
+
1523
+        $this->assertEquals(null, $share->getExpirationDate());
1524
+    }
1525
+
1526
+    public function testValidateExpirationDateInPast(): void {
1527
+        $this->expectException(GenericShareException::class);
1528
+        $this->expectExceptionMessage('Expiration date is in the past');
1529
+
1530
+        // Expire date in the past
1531
+        $past = new \DateTime();
1532
+        $past->sub(new \DateInterval('P1D'));
1533
+
1534
+        $share = $this->manager->newShare();
1535
+        $share->setExpirationDate($past);
1536
+
1537
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1538
+    }
1539
+
1540
+    public function testValidateExpirationDateEnforceButNotSet(): void {
1541
+        $this->expectException(\InvalidArgumentException::class);
1542
+        $this->expectExceptionMessage('Expiration date is enforced');
1543
+
1544
+        $share = $this->manager->newShare();
1545
+        $share->setProviderId('foo')->setId('bar');
1546
+
1547
+        $this->appConfig->method('getValueBool')
1548
+            ->willReturnMap([
1549
+                ['core', 'shareapi_default_expire_date', true],
1550
+                ['core', 'shareapi_enforce_expire_date', true],
1551
+            ]);
1552
+
1553
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1554
+    }
1555
+
1556
+    public function testValidateExpirationDateEnforceButNotEnabledAndNotSet(): void {
1557
+        $share = $this->manager->newShare();
1558
+        $share->setProviderId('foo')->setId('bar');
1559
+
1560
+        $this->config->method('getAppValue')
1561
+            ->willReturnMap([
1562
+                ['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
1563
+            ]);
1564
+
1565
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1566
+
1567
+        $this->assertNull($share->getExpirationDate());
1568
+    }
1569
+
1570
+    public function testValidateExpirationDateEnforceButNotSetNewShare(): void {
1571
+        $share = $this->manager->newShare();
1572
+
1573
+        $this->config->method('getAppValue')
1574
+            ->willReturnMap([
1575
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1576
+                ['core', 'link_defaultExpDays', '3', '3'],
1577
+            ]);
1578
+
1579
+        $this->appConfig->method('getValueBool')
1580
+            ->willReturnMap([
1581
+                ['core', 'shareapi_default_expire_date', true],
1582
+                ['core', 'shareapi_enforce_expire_date', true],
1583
+            ]);
1584
+
1585
+        $expected = new \DateTime('now', $this->timezone);
1586
+        $expected->setTime(0, 0, 0);
1587
+        $expected->add(new \DateInterval('P3D'));
1588
+
1589
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1590
+
1591
+        $this->assertNotNull($share->getExpirationDate());
1592
+        $this->assertEquals($expected, $share->getExpirationDate());
1593
+    }
1594
+
1595
+    public function testValidateExpirationDateEnforceRelaxedDefaultButNotSetNewShare(): void {
1596
+        $share = $this->manager->newShare();
1597
+
1598
+        $this->config->method('getAppValue')
1599
+            ->willReturnMap([
1600
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1601
+                ['core', 'link_defaultExpDays', '3', '1'],
1602
+            ]);
1603
+
1604
+        $this->appConfig->method('getValueBool')
1605
+            ->willReturnMap([
1606
+                ['core', 'shareapi_default_expire_date', true],
1607
+                ['core', 'shareapi_enforce_expire_date', true],
1608
+            ]);
1609
+
1610
+        $expected = new \DateTime('now', $this->timezone);
1611
+        $expected->setTime(0, 0, 0);
1612
+        $expected->add(new \DateInterval('P1D'));
1613 1613
 
1614
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1614
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1615 1615
 
1616
-		$this->assertNotNull($share->getExpirationDate());
1617
-		$this->assertEquals($expected, $share->getExpirationDate());
1618
-	}
1616
+        $this->assertNotNull($share->getExpirationDate());
1617
+        $this->assertEquals($expected, $share->getExpirationDate());
1618
+    }
1619 1619
 
1620
-	public function testValidateExpirationDateEnforceTooFarIntoFuture(): void {
1621
-		$this->expectException(GenericShareException::class);
1622
-		$this->expectExceptionMessage('Cannot set expiration date more than 3 days in the future');
1620
+    public function testValidateExpirationDateEnforceTooFarIntoFuture(): void {
1621
+        $this->expectException(GenericShareException::class);
1622
+        $this->expectExceptionMessage('Cannot set expiration date more than 3 days in the future');
1623 1623
 
1624
-		$future = new \DateTime();
1625
-		$future->add(new \DateInterval('P7D'));
1624
+        $future = new \DateTime();
1625
+        $future->add(new \DateInterval('P7D'));
1626 1626
 
1627
-		$share = $this->manager->newShare();
1628
-		$share->setExpirationDate($future);
1627
+        $share = $this->manager->newShare();
1628
+        $share->setExpirationDate($future);
1629 1629
 
1630
-		$this->config->method('getAppValue')
1631
-			->willReturnMap([
1632
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1633
-			]);
1630
+        $this->config->method('getAppValue')
1631
+            ->willReturnMap([
1632
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1633
+            ]);
1634 1634
 
1635
-		$this->appConfig->method('getValueBool')
1636
-			->willReturnMap([
1637
-				['core', 'shareapi_default_expire_date', true],
1638
-				['core', 'shareapi_enforce_expire_date', true],
1639
-			]);
1640
-
1641
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1642
-	}
1635
+        $this->appConfig->method('getValueBool')
1636
+            ->willReturnMap([
1637
+                ['core', 'shareapi_default_expire_date', true],
1638
+                ['core', 'shareapi_enforce_expire_date', true],
1639
+            ]);
1640
+
1641
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1642
+    }
1643 1643
 
1644
-	public function testValidateExpirationDateEnforceValid(): void {
1645
-		$future = new \DateTime('now', $this->timezone);
1646
-		$future->add(new \DateInterval('P2D'));
1647
-		$future->setTime(1, 2, 3);
1648
-
1649
-		$expected = clone $future;
1650
-		$expected->setTime(0, 0, 0);
1644
+    public function testValidateExpirationDateEnforceValid(): void {
1645
+        $future = new \DateTime('now', $this->timezone);
1646
+        $future->add(new \DateInterval('P2D'));
1647
+        $future->setTime(1, 2, 3);
1648
+
1649
+        $expected = clone $future;
1650
+        $expected->setTime(0, 0, 0);
1651 1651
 
1652
-		$share = $this->manager->newShare();
1653
-		$share->setExpirationDate($future);
1652
+        $share = $this->manager->newShare();
1653
+        $share->setExpirationDate($future);
1654 1654
 
1655
-		$this->config->method('getAppValue')
1656
-			->willReturnMap([
1657
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1658
-			]);
1655
+        $this->config->method('getAppValue')
1656
+            ->willReturnMap([
1657
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1658
+            ]);
1659 1659
 
1660
-		$this->appConfig->method('getValueBool')
1661
-			->willReturnMap([
1662
-				['core', 'shareapi_default_expire_date', true],
1663
-				['core', 'shareapi_enforce_expire_date', true],
1664
-			]);
1665
-
1666
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1667
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1668
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($future) {
1669
-			return $data['expirationDate'] == $future;
1670
-		}));
1671
-
1672
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1673
-
1674
-		$this->assertEquals($expected, $share->getExpirationDate());
1675
-	}
1676
-
1677
-	public function testValidateExpirationDateNoDefault(): void {
1678
-		$date = new \DateTime('now', $this->timezone);
1679
-		$date->add(new \DateInterval('P5D'));
1680
-		$date->setTime(1, 2, 3);
1681
-
1682
-		$expected = clone $date;
1683
-		$expected->setTime(0, 0);
1684
-		$expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1685
-
1686
-		$share = $this->manager->newShare();
1687
-		$share->setExpirationDate($date);
1688
-
1689
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1690
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1691
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1692
-			return $data['expirationDate'] == $expected && $data['passwordSet'] === false;
1693
-		}));
1694
-
1695
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1696
-
1697
-		$this->assertEquals($expected, $share->getExpirationDate());
1698
-	}
1699
-
1700
-	public function testValidateExpirationDateNoDateNoDefault(): void {
1701
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1702
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1703
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) {
1704
-			return $data['expirationDate'] === null && $data['passwordSet'] === true;
1705
-		}));
1706
-
1707
-		$share = $this->manager->newShare();
1708
-		$share->setPassword('password');
1709
-
1710
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1711
-
1712
-		$this->assertNull($share->getExpirationDate());
1713
-	}
1714
-
1715
-	public function testValidateExpirationDateNoDateDefault(): void {
1716
-		$share = $this->manager->newShare();
1717
-
1718
-		$expected = new \DateTime('now', $this->timezone);
1719
-		$expected->add(new \DateInterval('P3D'));
1720
-		$expected->setTime(0, 0);
1721
-		$expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1722
-
1723
-		$this->config->method('getAppValue')
1724
-			->willReturnMap([
1725
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1726
-				['core', 'link_defaultExpDays', '3', '3'],
1727
-			]);
1728
-
1729
-		$this->appConfig->method('getValueBool')
1730
-			->willReturnMap([
1731
-				['core', 'shareapi_default_expire_date', true],
1732
-				['core', 'shareapi_enforce_expire_date', false],
1733
-			]);
1734
-
1735
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1736
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1737
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1738
-			return $data['expirationDate'] == $expected;
1739
-		}));
1740
-
1741
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1742
-
1743
-		$this->assertEquals($expected, $share->getExpirationDate());
1744
-	}
1745
-
1746
-	public function testValidateExpirationDateDefault(): void {
1747
-		$future = new \DateTime('now', $this->timezone);
1748
-		$future->add(new \DateInterval('P5D'));
1749
-		$future->setTime(1, 2, 3);
1750
-
1751
-		$expected = clone $future;
1752
-		$expected->setTime(0, 0);
1753
-		$expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1754
-
1755
-		$share = $this->manager->newShare();
1756
-		$share->setExpirationDate($future);
1757
-
1758
-		$this->config->method('getAppValue')
1759
-			->willReturnMap([
1760
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1761
-				['core', 'link_defaultExpDays', '3', '1'],
1762
-			]);
1763
-
1764
-		$this->appConfig->method('getValueBool')
1765
-			->willReturnMap([
1766
-				['core', 'shareapi_default_expire_date', true],
1767
-				['core', 'shareapi_enforce_expire_date', false],
1768
-			]);
1769
-
1770
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1771
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1772
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1773
-			return $data['expirationDate'] == $expected;
1774
-		}));
1775
-
1776
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1777
-
1778
-		$this->assertEquals($expected, $share->getExpirationDate());
1779
-	}
1780
-
1781
-	public function testValidateExpirationNegativeOffsetTimezone(): void {
1782
-		$this->timezone = new \DateTimeZone('Pacific/Tahiti');
1783
-		$future = new \DateTime();
1784
-		$future->add(new \DateInterval('P5D'));
1785
-
1786
-		$expected = clone $future;
1787
-		$expected->setTimezone($this->timezone);
1788
-		$expected->setTime(0, 0);
1789
-		$expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1790
-
1791
-		$share = $this->manager->newShare();
1792
-		$share->setExpirationDate($future);
1793
-
1794
-		$this->config->method('getAppValue')
1795
-			->willReturnMap([
1796
-				['core', 'shareapi_expire_after_n_days', '7', '3'],
1797
-				['core', 'link_defaultExpDays', '3', '1'],
1798
-			]);
1799
-
1800
-		$this->appConfig->method('getValueBool')
1801
-			->willReturnMap([
1802
-				['core', 'shareapi_default_expire_date', true],
1803
-				['core', 'shareapi_enforce_expire_date', false],
1804
-			]);
1805
-
1806
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1807
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1808
-		$hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1809
-			return $data['expirationDate'] == $expected;
1810
-		}));
1811
-
1812
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1813
-
1814
-		$this->assertEquals($expected, $share->getExpirationDate());
1815
-	}
1816
-
1817
-	public function testValidateExpirationDateHookModification(): void {
1818
-		$nextWeek = new \DateTime('now', $this->timezone);
1819
-		$nextWeek->add(new \DateInterval('P7D'));
1820
-
1821
-		$save = clone $nextWeek;
1822
-		$save->setTime(0, 0);
1823
-		$save->sub(new \DateInterval('P2D'));
1824
-		$save->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1825
-
1826
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1827
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1828
-		$hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1829
-			$data['expirationDate']->sub(new \DateInterval('P2D'));
1830
-		});
1831
-
1832
-		$share = $this->manager->newShare();
1833
-		$share->setExpirationDate($nextWeek);
1834
-
1835
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1836
-
1837
-		$this->assertEquals($save, $share->getExpirationDate());
1838
-	}
1839
-
1840
-	public function testValidateExpirationDateHookException(): void {
1841
-		$this->expectException(\Exception::class);
1842
-		$this->expectExceptionMessage('Invalid date!');
1843
-
1844
-		$nextWeek = new \DateTime();
1845
-		$nextWeek->add(new \DateInterval('P7D'));
1846
-		$nextWeek->setTime(0, 0, 0);
1847
-
1848
-		$share = $this->manager->newShare();
1849
-		$share->setExpirationDate($nextWeek);
1850
-
1851
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
1852
-		Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1853
-		$hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1854
-			$data['accepted'] = false;
1855
-			$data['message'] = 'Invalid date!';
1856
-		});
1857
-
1858
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1859
-	}
1860
-
1861
-	public function testValidateExpirationDateExistingShareNoDefault(): void {
1862
-		$share = $this->manager->newShare();
1863
-
1864
-		$share->setId('42')->setProviderId('foo');
1865
-
1866
-		$this->config->method('getAppValue')
1867
-			->willReturnMap([
1868
-				['core', 'shareapi_expire_after_n_days', '7', '6'],
1869
-			]);
1870
-
1871
-		$this->appConfig->method('getValueBool')
1872
-			->willReturnMap([
1873
-				['core', 'shareapi_default_expire_date', true],
1874
-				['core', 'shareapi_enforce_expire_date', false],
1875
-			]);
1876
-		self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1877
-
1878
-		$this->assertEquals(null, $share->getExpirationDate());
1879
-	}
1880
-
1881
-	public function testUserCreateChecksShareWithGroupMembersOnlyDifferentGroups(): void {
1882
-		$this->expectException(\Exception::class);
1883
-		$this->expectExceptionMessage('Sharing is only allowed with group members');
1884
-
1885
-		$share = $this->manager->newShare();
1886
-
1887
-		$sharedBy = $this->createMock(IUser::class);
1888
-		$sharedWith = $this->createMock(IUser::class);
1889
-		$share->setSharedBy('sharedBy')->setSharedWith('sharedWith');
1660
+        $this->appConfig->method('getValueBool')
1661
+            ->willReturnMap([
1662
+                ['core', 'shareapi_default_expire_date', true],
1663
+                ['core', 'shareapi_enforce_expire_date', true],
1664
+            ]);
1665
+
1666
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1667
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1668
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($future) {
1669
+            return $data['expirationDate'] == $future;
1670
+        }));
1671
+
1672
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1673
+
1674
+        $this->assertEquals($expected, $share->getExpirationDate());
1675
+    }
1676
+
1677
+    public function testValidateExpirationDateNoDefault(): void {
1678
+        $date = new \DateTime('now', $this->timezone);
1679
+        $date->add(new \DateInterval('P5D'));
1680
+        $date->setTime(1, 2, 3);
1681
+
1682
+        $expected = clone $date;
1683
+        $expected->setTime(0, 0);
1684
+        $expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1685
+
1686
+        $share = $this->manager->newShare();
1687
+        $share->setExpirationDate($date);
1688
+
1689
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1690
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1691
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1692
+            return $data['expirationDate'] == $expected && $data['passwordSet'] === false;
1693
+        }));
1694
+
1695
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1696
+
1697
+        $this->assertEquals($expected, $share->getExpirationDate());
1698
+    }
1699
+
1700
+    public function testValidateExpirationDateNoDateNoDefault(): void {
1701
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1702
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1703
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) {
1704
+            return $data['expirationDate'] === null && $data['passwordSet'] === true;
1705
+        }));
1706
+
1707
+        $share = $this->manager->newShare();
1708
+        $share->setPassword('password');
1709
+
1710
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1711
+
1712
+        $this->assertNull($share->getExpirationDate());
1713
+    }
1714
+
1715
+    public function testValidateExpirationDateNoDateDefault(): void {
1716
+        $share = $this->manager->newShare();
1717
+
1718
+        $expected = new \DateTime('now', $this->timezone);
1719
+        $expected->add(new \DateInterval('P3D'));
1720
+        $expected->setTime(0, 0);
1721
+        $expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1722
+
1723
+        $this->config->method('getAppValue')
1724
+            ->willReturnMap([
1725
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1726
+                ['core', 'link_defaultExpDays', '3', '3'],
1727
+            ]);
1728
+
1729
+        $this->appConfig->method('getValueBool')
1730
+            ->willReturnMap([
1731
+                ['core', 'shareapi_default_expire_date', true],
1732
+                ['core', 'shareapi_enforce_expire_date', false],
1733
+            ]);
1734
+
1735
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1736
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1737
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1738
+            return $data['expirationDate'] == $expected;
1739
+        }));
1740
+
1741
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1742
+
1743
+        $this->assertEquals($expected, $share->getExpirationDate());
1744
+    }
1745
+
1746
+    public function testValidateExpirationDateDefault(): void {
1747
+        $future = new \DateTime('now', $this->timezone);
1748
+        $future->add(new \DateInterval('P5D'));
1749
+        $future->setTime(1, 2, 3);
1750
+
1751
+        $expected = clone $future;
1752
+        $expected->setTime(0, 0);
1753
+        $expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1754
+
1755
+        $share = $this->manager->newShare();
1756
+        $share->setExpirationDate($future);
1757
+
1758
+        $this->config->method('getAppValue')
1759
+            ->willReturnMap([
1760
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1761
+                ['core', 'link_defaultExpDays', '3', '1'],
1762
+            ]);
1763
+
1764
+        $this->appConfig->method('getValueBool')
1765
+            ->willReturnMap([
1766
+                ['core', 'shareapi_default_expire_date', true],
1767
+                ['core', 'shareapi_enforce_expire_date', false],
1768
+            ]);
1769
+
1770
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1771
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1772
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1773
+            return $data['expirationDate'] == $expected;
1774
+        }));
1775
+
1776
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1777
+
1778
+        $this->assertEquals($expected, $share->getExpirationDate());
1779
+    }
1780
+
1781
+    public function testValidateExpirationNegativeOffsetTimezone(): void {
1782
+        $this->timezone = new \DateTimeZone('Pacific/Tahiti');
1783
+        $future = new \DateTime();
1784
+        $future->add(new \DateInterval('P5D'));
1785
+
1786
+        $expected = clone $future;
1787
+        $expected->setTimezone($this->timezone);
1788
+        $expected->setTime(0, 0);
1789
+        $expected->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1790
+
1791
+        $share = $this->manager->newShare();
1792
+        $share->setExpirationDate($future);
1793
+
1794
+        $this->config->method('getAppValue')
1795
+            ->willReturnMap([
1796
+                ['core', 'shareapi_expire_after_n_days', '7', '3'],
1797
+                ['core', 'link_defaultExpDays', '3', '1'],
1798
+            ]);
1799
+
1800
+        $this->appConfig->method('getValueBool')
1801
+            ->willReturnMap([
1802
+                ['core', 'shareapi_default_expire_date', true],
1803
+                ['core', 'shareapi_enforce_expire_date', false],
1804
+            ]);
1805
+
1806
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1807
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1808
+        $hookListener->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
1809
+            return $data['expirationDate'] == $expected;
1810
+        }));
1811
+
1812
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1813
+
1814
+        $this->assertEquals($expected, $share->getExpirationDate());
1815
+    }
1816
+
1817
+    public function testValidateExpirationDateHookModification(): void {
1818
+        $nextWeek = new \DateTime('now', $this->timezone);
1819
+        $nextWeek->add(new \DateInterval('P7D'));
1820
+
1821
+        $save = clone $nextWeek;
1822
+        $save->setTime(0, 0);
1823
+        $save->sub(new \DateInterval('P2D'));
1824
+        $save->setTimezone(new \DateTimeZone(date_default_timezone_get()));
1825
+
1826
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1827
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1828
+        $hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1829
+            $data['expirationDate']->sub(new \DateInterval('P2D'));
1830
+        });
1831
+
1832
+        $share = $this->manager->newShare();
1833
+        $share->setExpirationDate($nextWeek);
1834
+
1835
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1836
+
1837
+        $this->assertEquals($save, $share->getExpirationDate());
1838
+    }
1839
+
1840
+    public function testValidateExpirationDateHookException(): void {
1841
+        $this->expectException(\Exception::class);
1842
+        $this->expectExceptionMessage('Invalid date!');
1843
+
1844
+        $nextWeek = new \DateTime();
1845
+        $nextWeek->add(new \DateInterval('P7D'));
1846
+        $nextWeek->setTime(0, 0, 0);
1847
+
1848
+        $share = $this->manager->newShare();
1849
+        $share->setExpirationDate($nextWeek);
1850
+
1851
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
1852
+        Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListener, 'listener');
1853
+        $hookListener->expects($this->once())->method('listener')->willReturnCallback(function ($data): void {
1854
+            $data['accepted'] = false;
1855
+            $data['message'] = 'Invalid date!';
1856
+        });
1857
+
1858
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1859
+    }
1860
+
1861
+    public function testValidateExpirationDateExistingShareNoDefault(): void {
1862
+        $share = $this->manager->newShare();
1863
+
1864
+        $share->setId('42')->setProviderId('foo');
1865
+
1866
+        $this->config->method('getAppValue')
1867
+            ->willReturnMap([
1868
+                ['core', 'shareapi_expire_after_n_days', '7', '6'],
1869
+            ]);
1870
+
1871
+        $this->appConfig->method('getValueBool')
1872
+            ->willReturnMap([
1873
+                ['core', 'shareapi_default_expire_date', true],
1874
+                ['core', 'shareapi_enforce_expire_date', false],
1875
+            ]);
1876
+        self::invokePrivate($this->manager, 'validateExpirationDateLink', [$share]);
1877
+
1878
+        $this->assertEquals(null, $share->getExpirationDate());
1879
+    }
1880
+
1881
+    public function testUserCreateChecksShareWithGroupMembersOnlyDifferentGroups(): void {
1882
+        $this->expectException(\Exception::class);
1883
+        $this->expectExceptionMessage('Sharing is only allowed with group members');
1884
+
1885
+        $share = $this->manager->newShare();
1886
+
1887
+        $sharedBy = $this->createMock(IUser::class);
1888
+        $sharedWith = $this->createMock(IUser::class);
1889
+        $share->setSharedBy('sharedBy')->setSharedWith('sharedWith');
1890 1890
 
1891
-		$this->groupManager
1892
-			->method('getUserGroupIds')
1893
-			->willReturnMap(
1894
-				[
1895
-					[$sharedBy, ['group1']],
1896
-					[$sharedWith, ['group2']],
1897
-				]
1898
-			);
1891
+        $this->groupManager
1892
+            ->method('getUserGroupIds')
1893
+            ->willReturnMap(
1894
+                [
1895
+                    [$sharedBy, ['group1']],
1896
+                    [$sharedWith, ['group2']],
1897
+                ]
1898
+            );
1899 1899
 
1900
-		$this->userManager->method('get')->willReturnMap([
1901
-			['sharedBy', $sharedBy],
1902
-			['sharedWith', $sharedWith],
1903
-		]);
1900
+        $this->userManager->method('get')->willReturnMap([
1901
+            ['sharedBy', $sharedBy],
1902
+            ['sharedWith', $sharedWith],
1903
+        ]);
1904 1904
 
1905
-		$this->config
1906
-			->method('getAppValue')
1907
-			->willReturnMap([
1908
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
1909
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
1910
-			]);
1905
+        $this->config
1906
+            ->method('getAppValue')
1907
+            ->willReturnMap([
1908
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
1909
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
1910
+            ]);
1911 1911
 
1912
-		self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
1913
-	}
1914
-
1915
-	public function testUserCreateChecksShareWithGroupMembersOnlySharedGroup(): void {
1916
-		$share = $this->manager->newShare();
1917
-
1918
-		$sharedBy = $this->createMock(IUser::class);
1919
-		$sharedWith = $this->createMock(IUser::class);
1920
-		$share->setSharedBy('sharedBy')->setSharedWith('sharedWith');
1921
-
1922
-		$path = $this->createMock(Node::class);
1923
-		$share->setNode($path);
1912
+        self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
1913
+    }
1914
+
1915
+    public function testUserCreateChecksShareWithGroupMembersOnlySharedGroup(): void {
1916
+        $share = $this->manager->newShare();
1917
+
1918
+        $sharedBy = $this->createMock(IUser::class);
1919
+        $sharedWith = $this->createMock(IUser::class);
1920
+        $share->setSharedBy('sharedBy')->setSharedWith('sharedWith');
1921
+
1922
+        $path = $this->createMock(Node::class);
1923
+        $share->setNode($path);
1924 1924
 
1925
-		$this->groupManager
1926
-			->method('getUserGroupIds')
1927
-			->willReturnMap(
1928
-				[
1929
-					[$sharedBy, ['group1', 'group3']],
1930
-					[$sharedWith, ['group2', 'group3']],
1931
-				]
1932
-			);
1925
+        $this->groupManager
1926
+            ->method('getUserGroupIds')
1927
+            ->willReturnMap(
1928
+                [
1929
+                    [$sharedBy, ['group1', 'group3']],
1930
+                    [$sharedWith, ['group2', 'group3']],
1931
+                ]
1932
+            );
1933 1933
 
1934
-		$this->userManager->method('get')->willReturnMap([
1935
-			['sharedBy', $sharedBy],
1936
-			['sharedWith', $sharedWith],
1937
-		]);
1934
+        $this->userManager->method('get')->willReturnMap([
1935
+            ['sharedBy', $sharedBy],
1936
+            ['sharedWith', $sharedWith],
1937
+        ]);
1938 1938
 
1939
-		$this->config
1940
-			->method('getAppValue')
1941
-			->willReturnMap([
1942
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
1943
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
1944
-			]);
1939
+        $this->config
1940
+            ->method('getAppValue')
1941
+            ->willReturnMap([
1942
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
1943
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
1944
+            ]);
1945 1945
 
1946
-		$this->defaultProvider
1947
-			->method('getSharesByPath')
1948
-			->with($path)
1949
-			->willReturn([]);
1946
+        $this->defaultProvider
1947
+            ->method('getSharesByPath')
1948
+            ->with($path)
1949
+            ->willReturn([]);
1950 1950
 
1951
-		self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
1952
-		$this->addToAssertionCount(1);
1953
-	}
1951
+        self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
1952
+        $this->addToAssertionCount(1);
1953
+    }
1954 1954
 
1955 1955
 
1956
-	public function testUserCreateChecksIdenticalShareExists(): void {
1957
-		$this->expectException(AlreadySharedException::class);
1958
-		$this->expectExceptionMessage('Sharing name.txt failed, because this item is already shared with the account user');
1956
+    public function testUserCreateChecksIdenticalShareExists(): void {
1957
+        $this->expectException(AlreadySharedException::class);
1958
+        $this->expectExceptionMessage('Sharing name.txt failed, because this item is already shared with the account user');
1959 1959
 
1960
-		$share = $this->manager->newShare();
1961
-		$share->setSharedWithDisplayName('user');
1962
-		$share2 = $this->manager->newShare();
1960
+        $share = $this->manager->newShare();
1961
+        $share->setSharedWithDisplayName('user');
1962
+        $share2 = $this->manager->newShare();
1963 1963
 
1964
-		$sharedWith = $this->createMock(IUser::class);
1965
-		$path = $this->createMock(Node::class);
1966
-
1967
-		$share->setSharedWith('sharedWith')->setNode($path)
1968
-			->setProviderId('foo')->setId('bar');
1969
-
1970
-		$share2->setSharedWith('sharedWith')->setNode($path)
1971
-			->setProviderId('foo')->setId('baz');
1972
-
1973
-		$this->defaultProvider
1974
-			->method('getSharesByPath')
1975
-			->with($path)
1976
-			->willReturn([$share2]);
1964
+        $sharedWith = $this->createMock(IUser::class);
1965
+        $path = $this->createMock(Node::class);
1966
+
1967
+        $share->setSharedWith('sharedWith')->setNode($path)
1968
+            ->setProviderId('foo')->setId('bar');
1969
+
1970
+        $share2->setSharedWith('sharedWith')->setNode($path)
1971
+            ->setProviderId('foo')->setId('baz');
1972
+
1973
+        $this->defaultProvider
1974
+            ->method('getSharesByPath')
1975
+            ->with($path)
1976
+            ->willReturn([$share2]);
1977 1977
 
1978
-		$path->method('getName')
1979
-			->willReturn('name.txt');
1978
+        $path->method('getName')
1979
+            ->willReturn('name.txt');
1980 1980
 
1981
-		self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
1982
-	}
1983
-
1984
-
1985
-	public function testUserCreateChecksIdenticalPathSharedViaGroup(): void {
1986
-		$this->expectException(AlreadySharedException::class);
1987
-		$this->expectExceptionMessage('Sharing name2.txt failed, because this item is already shared with the account userName');
1988
-
1989
-		$share = $this->manager->newShare();
1981
+        self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
1982
+    }
1983
+
1984
+
1985
+    public function testUserCreateChecksIdenticalPathSharedViaGroup(): void {
1986
+        $this->expectException(AlreadySharedException::class);
1987
+        $this->expectExceptionMessage('Sharing name2.txt failed, because this item is already shared with the account userName');
1988
+
1989
+        $share = $this->manager->newShare();
1990 1990
 
1991
-		$sharedWith = $this->createMock(IUser::class);
1992
-		$sharedWith->method('getUID')->willReturn('sharedWith');
1993
-
1994
-		$this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
1991
+        $sharedWith = $this->createMock(IUser::class);
1992
+        $sharedWith->method('getUID')->willReturn('sharedWith');
1993
+
1994
+        $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
1995 1995
 
1996
-		$path = $this->createMock(Node::class);
1996
+        $path = $this->createMock(Node::class);
1997 1997
 
1998
-		$share->setSharedWith('sharedWith')
1999
-			->setNode($path)
2000
-			->setShareOwner('shareOwner')
2001
-			->setSharedWithDisplayName('userName')
2002
-			->setProviderId('foo')
2003
-			->setId('bar');
1998
+        $share->setSharedWith('sharedWith')
1999
+            ->setNode($path)
2000
+            ->setShareOwner('shareOwner')
2001
+            ->setSharedWithDisplayName('userName')
2002
+            ->setProviderId('foo')
2003
+            ->setId('bar');
2004 2004
 
2005
-		$share2 = $this->manager->newShare();
2006
-		$share2->setShareType(IShare::TYPE_GROUP)
2007
-			->setShareOwner('shareOwner2')
2008
-			->setProviderId('foo')
2009
-			->setId('baz')
2010
-			->setSharedWith('group');
2005
+        $share2 = $this->manager->newShare();
2006
+        $share2->setShareType(IShare::TYPE_GROUP)
2007
+            ->setShareOwner('shareOwner2')
2008
+            ->setProviderId('foo')
2009
+            ->setId('baz')
2010
+            ->setSharedWith('group');
2011 2011
 
2012
-		$group = $this->createMock(IGroup::class);
2013
-		$group->method('inGroup')
2014
-			->with($sharedWith)
2015
-			->willReturn(true);
2012
+        $group = $this->createMock(IGroup::class);
2013
+        $group->method('inGroup')
2014
+            ->with($sharedWith)
2015
+            ->willReturn(true);
2016 2016
 
2017
-		$this->groupManager->method('get')->with('group')->willReturn($group);
2017
+        $this->groupManager->method('get')->with('group')->willReturn($group);
2018 2018
 
2019
-		$this->defaultProvider
2020
-			->method('getSharesByPath')
2021
-			->with($path)
2022
-			->willReturn([$share2]);
2019
+        $this->defaultProvider
2020
+            ->method('getSharesByPath')
2021
+            ->with($path)
2022
+            ->willReturn([$share2]);
2023 2023
 
2024
-		$path->method('getName')
2025
-			->willReturn('name2.txt');
2024
+        $path->method('getName')
2025
+            ->willReturn('name2.txt');
2026 2026
 
2027
-		self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
2028
-	}
2027
+        self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
2028
+    }
2029 2029
 
2030
-	public function testUserCreateChecksIdenticalPathSharedViaDeletedGroup(): void {
2031
-		$share = $this->manager->newShare();
2030
+    public function testUserCreateChecksIdenticalPathSharedViaDeletedGroup(): void {
2031
+        $share = $this->manager->newShare();
2032 2032
 
2033
-		$sharedWith = $this->createMock(IUser::class);
2034
-		$sharedWith->method('getUID')->willReturn('sharedWith');
2033
+        $sharedWith = $this->createMock(IUser::class);
2034
+        $sharedWith->method('getUID')->willReturn('sharedWith');
2035 2035
 
2036
-		$this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
2036
+        $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
2037 2037
 
2038
-		$path = $this->createMock(Node::class);
2038
+        $path = $this->createMock(Node::class);
2039 2039
 
2040
-		$share->setSharedWith('sharedWith')
2041
-			->setNode($path)
2042
-			->setShareOwner('shareOwner')
2043
-			->setProviderId('foo')
2044
-			->setId('bar');
2040
+        $share->setSharedWith('sharedWith')
2041
+            ->setNode($path)
2042
+            ->setShareOwner('shareOwner')
2043
+            ->setProviderId('foo')
2044
+            ->setId('bar');
2045 2045
 
2046
-		$share2 = $this->manager->newShare();
2047
-		$share2->setShareType(IShare::TYPE_GROUP)
2048
-			->setShareOwner('shareOwner2')
2049
-			->setProviderId('foo')
2050
-			->setId('baz')
2051
-			->setSharedWith('group');
2046
+        $share2 = $this->manager->newShare();
2047
+        $share2->setShareType(IShare::TYPE_GROUP)
2048
+            ->setShareOwner('shareOwner2')
2049
+            ->setProviderId('foo')
2050
+            ->setId('baz')
2051
+            ->setSharedWith('group');
2052 2052
 
2053
-		$this->groupManager->method('get')->with('group')->willReturn(null);
2053
+        $this->groupManager->method('get')->with('group')->willReturn(null);
2054 2054
 
2055
-		$this->defaultProvider
2056
-			->method('getSharesByPath')
2057
-			->with($path)
2058
-			->willReturn([$share2]);
2055
+        $this->defaultProvider
2056
+            ->method('getSharesByPath')
2057
+            ->with($path)
2058
+            ->willReturn([$share2]);
2059 2059
 
2060
-		$this->assertNull($this->invokePrivate($this->manager, 'userCreateChecks', [$share]));
2061
-	}
2060
+        $this->assertNull($this->invokePrivate($this->manager, 'userCreateChecks', [$share]));
2061
+    }
2062 2062
 
2063
-	public function testUserCreateChecksIdenticalPathNotSharedWithUser(): void {
2064
-		$share = $this->manager->newShare();
2065
-		$sharedWith = $this->createMock(IUser::class);
2066
-		$path = $this->createMock(Node::class);
2067
-		$share->setSharedWith('sharedWith')
2068
-			->setNode($path)
2069
-			->setShareOwner('shareOwner')
2070
-			->setProviderId('foo')
2071
-			->setId('bar');
2063
+    public function testUserCreateChecksIdenticalPathNotSharedWithUser(): void {
2064
+        $share = $this->manager->newShare();
2065
+        $sharedWith = $this->createMock(IUser::class);
2066
+        $path = $this->createMock(Node::class);
2067
+        $share->setSharedWith('sharedWith')
2068
+            ->setNode($path)
2069
+            ->setShareOwner('shareOwner')
2070
+            ->setProviderId('foo')
2071
+            ->setId('bar');
2072 2072
 
2073
-		$this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
2073
+        $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith);
2074 2074
 
2075
-		$share2 = $this->manager->newShare();
2076
-		$share2->setShareType(IShare::TYPE_GROUP)
2077
-			->setShareOwner('shareOwner2')
2078
-			->setProviderId('foo')
2079
-			->setId('baz');
2075
+        $share2 = $this->manager->newShare();
2076
+        $share2->setShareType(IShare::TYPE_GROUP)
2077
+            ->setShareOwner('shareOwner2')
2078
+            ->setProviderId('foo')
2079
+            ->setId('baz');
2080 2080
 
2081
-		$group = $this->createMock(IGroup::class);
2082
-		$group->method('inGroup')
2083
-			->with($sharedWith)
2084
-			->willReturn(false);
2081
+        $group = $this->createMock(IGroup::class);
2082
+        $group->method('inGroup')
2083
+            ->with($sharedWith)
2084
+            ->willReturn(false);
2085 2085
 
2086
-		$this->groupManager->method('get')->with('group')->willReturn($group);
2086
+        $this->groupManager->method('get')->with('group')->willReturn($group);
2087 2087
 
2088
-		$share2->setSharedWith('group');
2088
+        $share2->setSharedWith('group');
2089 2089
 
2090
-		$this->defaultProvider
2091
-			->method('getSharesByPath')
2092
-			->with($path)
2093
-			->willReturn([$share2]);
2090
+        $this->defaultProvider
2091
+            ->method('getSharesByPath')
2092
+            ->with($path)
2093
+            ->willReturn([$share2]);
2094 2094
 
2095
-		self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
2096
-		$this->addToAssertionCount(1);
2097
-	}
2095
+        self::invokePrivate($this->manager, 'userCreateChecks', [$share]);
2096
+        $this->addToAssertionCount(1);
2097
+    }
2098 2098
 
2099 2099
 
2100
-	public function testGroupCreateChecksShareWithGroupMembersGroupSharingNotAllowed(): void {
2101
-		$this->expectException(\Exception::class);
2102
-		$this->expectExceptionMessage('Group sharing is now allowed');
2100
+    public function testGroupCreateChecksShareWithGroupMembersGroupSharingNotAllowed(): void {
2101
+        $this->expectException(\Exception::class);
2102
+        $this->expectExceptionMessage('Group sharing is now allowed');
2103 2103
 
2104
-		$share = $this->manager->newShare();
2104
+        $share = $this->manager->newShare();
2105 2105
 
2106
-		$this->config
2107
-			->method('getAppValue')
2108
-			->willReturnMap([
2109
-				['core', 'shareapi_allow_group_sharing', 'yes', 'no'],
2110
-			]);
2106
+        $this->config
2107
+            ->method('getAppValue')
2108
+            ->willReturnMap([
2109
+                ['core', 'shareapi_allow_group_sharing', 'yes', 'no'],
2110
+            ]);
2111 2111
 
2112
-		self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2113
-	}
2112
+        self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2113
+    }
2114 2114
 
2115 2115
 
2116
-	public function testGroupCreateChecksShareWithGroupMembersOnlyNotInGroup(): void {
2117
-		$this->expectException(\Exception::class);
2118
-		$this->expectExceptionMessage('Sharing is only allowed within your own groups');
2116
+    public function testGroupCreateChecksShareWithGroupMembersOnlyNotInGroup(): void {
2117
+        $this->expectException(\Exception::class);
2118
+        $this->expectExceptionMessage('Sharing is only allowed within your own groups');
2119 2119
 
2120
-		$share = $this->manager->newShare();
2120
+        $share = $this->manager->newShare();
2121 2121
 
2122
-		$user = $this->createMock(IUser::class);
2123
-		$group = $this->createMock(IGroup::class);
2124
-		$share->setSharedBy('user')->setSharedWith('group');
2122
+        $user = $this->createMock(IUser::class);
2123
+        $group = $this->createMock(IGroup::class);
2124
+        $share->setSharedBy('user')->setSharedWith('group');
2125 2125
 
2126
-		$group->method('inGroup')->with($user)->willReturn(false);
2126
+        $group->method('inGroup')->with($user)->willReturn(false);
2127 2127
 
2128
-		$this->groupManager->method('get')->with('group')->willReturn($group);
2129
-		$this->userManager->method('get')->with('user')->willReturn($user);
2128
+        $this->groupManager->method('get')->with('group')->willReturn($group);
2129
+        $this->userManager->method('get')->with('user')->willReturn($user);
2130 2130
 
2131
-		$this->config
2132
-			->method('getAppValue')
2133
-			->willReturnMap([
2134
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
2135
-				['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2136
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
2137
-			]);
2131
+        $this->config
2132
+            ->method('getAppValue')
2133
+            ->willReturnMap([
2134
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
2135
+                ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2136
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
2137
+            ]);
2138 2138
 
2139
-		self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2140
-	}
2139
+        self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2140
+    }
2141 2141
 
2142 2142
 
2143
-	public function testGroupCreateChecksShareWithGroupMembersOnlyNullGroup(): void {
2144
-		$this->expectException(\Exception::class);
2145
-		$this->expectExceptionMessage('Sharing is only allowed within your own groups');
2143
+    public function testGroupCreateChecksShareWithGroupMembersOnlyNullGroup(): void {
2144
+        $this->expectException(\Exception::class);
2145
+        $this->expectExceptionMessage('Sharing is only allowed within your own groups');
2146 2146
 
2147
-		$share = $this->manager->newShare();
2147
+        $share = $this->manager->newShare();
2148 2148
 
2149
-		$user = $this->createMock(IUser::class);
2150
-		$share->setSharedBy('user')->setSharedWith('group');
2149
+        $user = $this->createMock(IUser::class);
2150
+        $share->setSharedBy('user')->setSharedWith('group');
2151 2151
 
2152
-		$this->groupManager->method('get')->with('group')->willReturn(null);
2153
-		$this->userManager->method('get')->with('user')->willReturn($user);
2152
+        $this->groupManager->method('get')->with('group')->willReturn(null);
2153
+        $this->userManager->method('get')->with('user')->willReturn($user);
2154 2154
 
2155
-		$this->config
2156
-			->method('getAppValue')
2157
-			->willReturnMap([
2158
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
2159
-				['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2160
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
2161
-			]);
2155
+        $this->config
2156
+            ->method('getAppValue')
2157
+            ->willReturnMap([
2158
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
2159
+                ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2160
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
2161
+            ]);
2162 2162
 
2163
-		$this->assertNull($this->invokePrivate($this->manager, 'groupCreateChecks', [$share]));
2164
-	}
2163
+        $this->assertNull($this->invokePrivate($this->manager, 'groupCreateChecks', [$share]));
2164
+    }
2165 2165
 
2166
-	public function testGroupCreateChecksShareWithGroupMembersOnlyInGroup(): void {
2167
-		$share = $this->manager->newShare();
2166
+    public function testGroupCreateChecksShareWithGroupMembersOnlyInGroup(): void {
2167
+        $share = $this->manager->newShare();
2168 2168
 
2169
-		$user = $this->createMock(IUser::class);
2170
-		$group = $this->createMock(IGroup::class);
2171
-		$share->setSharedBy('user')->setSharedWith('group');
2169
+        $user = $this->createMock(IUser::class);
2170
+        $group = $this->createMock(IGroup::class);
2171
+        $share->setSharedBy('user')->setSharedWith('group');
2172 2172
 
2173
-		$this->userManager->method('get')->with('user')->willReturn($user);
2174
-		$this->groupManager->method('get')->with('group')->willReturn($group);
2173
+        $this->userManager->method('get')->with('user')->willReturn($user);
2174
+        $this->groupManager->method('get')->with('group')->willReturn($group);
2175 2175
 
2176
-		$group->method('inGroup')->with($user)->willReturn(true);
2176
+        $group->method('inGroup')->with($user)->willReturn(true);
2177 2177
 
2178
-		$path = $this->createMock(Node::class);
2179
-		$share->setNode($path);
2178
+        $path = $this->createMock(Node::class);
2179
+        $share->setNode($path);
2180 2180
 
2181
-		$this->defaultProvider->method('getSharesByPath')
2182
-			->with($path)
2183
-			->willReturn([]);
2181
+        $this->defaultProvider->method('getSharesByPath')
2182
+            ->with($path)
2183
+            ->willReturn([]);
2184 2184
 
2185
-		$this->config
2186
-			->method('getAppValue')
2187
-			->willReturnMap([
2188
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
2189
-				['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2190
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
2191
-			]);
2185
+        $this->config
2186
+            ->method('getAppValue')
2187
+            ->willReturnMap([
2188
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
2189
+                ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2190
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
2191
+            ]);
2192 2192
 
2193
-		self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2194
-		$this->addToAssertionCount(1);
2195
-	}
2193
+        self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2194
+        $this->addToAssertionCount(1);
2195
+    }
2196 2196
 
2197 2197
 
2198
-	public function testGroupCreateChecksPathAlreadySharedWithSameGroup(): void {
2199
-		$this->expectException(\Exception::class);
2200
-		$this->expectExceptionMessage('Path is already shared with this group');
2198
+    public function testGroupCreateChecksPathAlreadySharedWithSameGroup(): void {
2199
+        $this->expectException(\Exception::class);
2200
+        $this->expectExceptionMessage('Path is already shared with this group');
2201 2201
 
2202
-		$share = $this->manager->newShare();
2202
+        $share = $this->manager->newShare();
2203 2203
 
2204
-		$path = $this->createMock(Node::class);
2205
-		$share->setSharedWith('sharedWith')
2206
-			->setNode($path)
2207
-			->setProviderId('foo')
2208
-			->setId('bar');
2204
+        $path = $this->createMock(Node::class);
2205
+        $share->setSharedWith('sharedWith')
2206
+            ->setNode($path)
2207
+            ->setProviderId('foo')
2208
+            ->setId('bar');
2209 2209
 
2210
-		$share2 = $this->manager->newShare();
2211
-		$share2->setSharedWith('sharedWith')
2212
-			->setProviderId('foo')
2213
-			->setId('baz');
2210
+        $share2 = $this->manager->newShare();
2211
+        $share2->setSharedWith('sharedWith')
2212
+            ->setProviderId('foo')
2213
+            ->setId('baz');
2214 2214
 
2215
-		$this->defaultProvider->method('getSharesByPath')
2216
-			->with($path)
2217
-			->willReturn([$share2]);
2215
+        $this->defaultProvider->method('getSharesByPath')
2216
+            ->with($path)
2217
+            ->willReturn([$share2]);
2218 2218
 
2219
-		$this->config
2220
-			->method('getAppValue')
2221
-			->willReturnMap([
2222
-				['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2223
-			]);
2219
+        $this->config
2220
+            ->method('getAppValue')
2221
+            ->willReturnMap([
2222
+                ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2223
+            ]);
2224 2224
 
2225
-		self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2226
-	}
2225
+        self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2226
+    }
2227 2227
 
2228
-	public function testGroupCreateChecksPathAlreadySharedWithDifferentGroup(): void {
2229
-		$share = $this->manager->newShare();
2228
+    public function testGroupCreateChecksPathAlreadySharedWithDifferentGroup(): void {
2229
+        $share = $this->manager->newShare();
2230 2230
 
2231
-		$share->setSharedWith('sharedWith');
2231
+        $share->setSharedWith('sharedWith');
2232 2232
 
2233
-		$path = $this->createMock(Node::class);
2234
-		$share->setNode($path);
2233
+        $path = $this->createMock(Node::class);
2234
+        $share->setNode($path);
2235 2235
 
2236
-		$share2 = $this->manager->newShare();
2237
-		$share2->setSharedWith('sharedWith2');
2236
+        $share2 = $this->manager->newShare();
2237
+        $share2->setSharedWith('sharedWith2');
2238 2238
 
2239
-		$this->defaultProvider->method('getSharesByPath')
2240
-			->with($path)
2241
-			->willReturn([$share2]);
2239
+        $this->defaultProvider->method('getSharesByPath')
2240
+            ->with($path)
2241
+            ->willReturn([$share2]);
2242 2242
 
2243
-		$this->config
2244
-			->method('getAppValue')
2245
-			->willReturnMap([
2246
-				['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2247
-			]);
2243
+        $this->config
2244
+            ->method('getAppValue')
2245
+            ->willReturnMap([
2246
+                ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
2247
+            ]);
2248 2248
 
2249
-		self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2250
-		$this->addToAssertionCount(1);
2251
-	}
2249
+        self::invokePrivate($this->manager, 'groupCreateChecks', [$share]);
2250
+        $this->addToAssertionCount(1);
2251
+    }
2252 2252
 
2253 2253
 
2254
-	public function testLinkCreateChecksNoLinkSharesAllowed(): void {
2255
-		$this->expectException(\Exception::class);
2256
-		$this->expectExceptionMessage('Link sharing is not allowed');
2254
+    public function testLinkCreateChecksNoLinkSharesAllowed(): void {
2255
+        $this->expectException(\Exception::class);
2256
+        $this->expectExceptionMessage('Link sharing is not allowed');
2257 2257
 
2258
-		$share = $this->manager->newShare();
2258
+        $share = $this->manager->newShare();
2259 2259
 
2260
-		$this->config
2261
-			->method('getAppValue')
2262
-			->willReturnMap([
2263
-				['core', 'shareapi_allow_links', 'yes', 'no'],
2264
-			]);
2260
+        $this->config
2261
+            ->method('getAppValue')
2262
+            ->willReturnMap([
2263
+                ['core', 'shareapi_allow_links', 'yes', 'no'],
2264
+            ]);
2265 2265
 
2266
-		self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2267
-	}
2266
+        self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2267
+    }
2268 2268
 
2269 2269
 
2270
-	public function testFileLinkCreateChecksNoPublicUpload(): void {
2271
-		$share = $this->manager->newShare();
2270
+    public function testFileLinkCreateChecksNoPublicUpload(): void {
2271
+        $share = $this->manager->newShare();
2272 2272
 
2273
-		$share->setPermissions(Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
2274
-		$share->setNodeType('file');
2273
+        $share->setPermissions(Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
2274
+        $share->setNodeType('file');
2275 2275
 
2276
-		$this->config
2277
-			->method('getAppValue')
2278
-			->willReturnMap([
2279
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
2280
-				['core', 'shareapi_allow_public_upload', 'yes', 'no']
2281
-			]);
2276
+        $this->config
2277
+            ->method('getAppValue')
2278
+            ->willReturnMap([
2279
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
2280
+                ['core', 'shareapi_allow_public_upload', 'yes', 'no']
2281
+            ]);
2282 2282
 
2283
-		self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2284
-		$this->addToAssertionCount(1);
2285
-	}
2283
+        self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2284
+        $this->addToAssertionCount(1);
2285
+    }
2286 2286
 
2287
-	public function testFolderLinkCreateChecksNoPublicUpload(): void {
2288
-		$this->expectException(\Exception::class);
2289
-		$this->expectExceptionMessage('Public upload is not allowed');
2287
+    public function testFolderLinkCreateChecksNoPublicUpload(): void {
2288
+        $this->expectException(\Exception::class);
2289
+        $this->expectExceptionMessage('Public upload is not allowed');
2290 2290
 
2291
-		$share = $this->manager->newShare();
2291
+        $share = $this->manager->newShare();
2292 2292
 
2293
-		$share->setPermissions(Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
2294
-		$share->setNodeType('folder');
2293
+        $share->setPermissions(Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
2294
+        $share->setNodeType('folder');
2295 2295
 
2296
-		$this->config
2297
-			->method('getAppValue')
2298
-			->willReturnMap([
2299
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
2300
-				['core', 'shareapi_allow_public_upload', 'yes', 'no']
2301
-			]);
2296
+        $this->config
2297
+            ->method('getAppValue')
2298
+            ->willReturnMap([
2299
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
2300
+                ['core', 'shareapi_allow_public_upload', 'yes', 'no']
2301
+            ]);
2302 2302
 
2303
-		self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2304
-	}
2303
+        self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2304
+    }
2305 2305
 
2306
-	public function testLinkCreateChecksPublicUpload(): void {
2307
-		$share = $this->manager->newShare();
2306
+    public function testLinkCreateChecksPublicUpload(): void {
2307
+        $share = $this->manager->newShare();
2308 2308
 
2309
-		$share->setPermissions(Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
2310
-		$share->setSharedWith('sharedWith');
2311
-		$folder = $this->createMock(\OC\Files\Node\Folder::class);
2312
-		$share->setNode($folder);
2309
+        $share->setPermissions(Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
2310
+        $share->setSharedWith('sharedWith');
2311
+        $folder = $this->createMock(\OC\Files\Node\Folder::class);
2312
+        $share->setNode($folder);
2313 2313
 
2314
-		$this->config
2315
-			->method('getAppValue')
2316
-			->willReturnMap([
2317
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
2318
-				['core', 'shareapi_allow_public_upload', 'yes', 'yes']
2319
-			]);
2314
+        $this->config
2315
+            ->method('getAppValue')
2316
+            ->willReturnMap([
2317
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
2318
+                ['core', 'shareapi_allow_public_upload', 'yes', 'yes']
2319
+            ]);
2320 2320
 
2321
-		self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2322
-		$this->addToAssertionCount(1);
2323
-	}
2321
+        self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2322
+        $this->addToAssertionCount(1);
2323
+    }
2324 2324
 
2325
-	public function testLinkCreateChecksReadOnly(): void {
2326
-		$share = $this->manager->newShare();
2325
+    public function testLinkCreateChecksReadOnly(): void {
2326
+        $share = $this->manager->newShare();
2327 2327
 
2328
-		$share->setPermissions(Constants::PERMISSION_READ);
2329
-		$share->setSharedWith('sharedWith');
2330
-		$folder = $this->createMock(\OC\Files\Node\Folder::class);
2331
-		$share->setNode($folder);
2328
+        $share->setPermissions(Constants::PERMISSION_READ);
2329
+        $share->setSharedWith('sharedWith');
2330
+        $folder = $this->createMock(\OC\Files\Node\Folder::class);
2331
+        $share->setNode($folder);
2332 2332
 
2333
-		$this->config
2334
-			->method('getAppValue')
2335
-			->willReturnMap([
2336
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
2337
-				['core', 'shareapi_allow_public_upload', 'yes', 'no']
2338
-			]);
2333
+        $this->config
2334
+            ->method('getAppValue')
2335
+            ->willReturnMap([
2336
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
2337
+                ['core', 'shareapi_allow_public_upload', 'yes', 'no']
2338
+            ]);
2339 2339
 
2340
-		self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2341
-		$this->addToAssertionCount(1);
2342
-	}
2343
-
2344
-
2345
-	public function testPathCreateChecksContainsSharedMount(): void {
2346
-		$this->expectException(\InvalidArgumentException::class);
2347
-		$this->expectExceptionMessage('You cannot share a folder that contains other shares');
2340
+        self::invokePrivate($this->manager, 'linkCreateChecks', [$share]);
2341
+        $this->addToAssertionCount(1);
2342
+    }
2343
+
2344
+
2345
+    public function testPathCreateChecksContainsSharedMount(): void {
2346
+        $this->expectException(\InvalidArgumentException::class);
2347
+        $this->expectExceptionMessage('You cannot share a folder that contains other shares');
2348 2348
 
2349
-		$path = $this->createMock(Folder::class);
2350
-		$path->method('getPath')->willReturn('path');
2349
+        $path = $this->createMock(Folder::class);
2350
+        $path->method('getPath')->willReturn('path');
2351 2351
 
2352
-		$mount = $this->createMock(IMountPoint::class);
2353
-		$storage = $this->createMock(IStorage::class);
2354
-		$mount->method('getStorage')->willReturn($storage);
2355
-		$storage->method('instanceOfStorage')->with('\OCA\Files_Sharing\ISharedStorage')->willReturn(true);
2356
-
2357
-		$this->mountManager->method('findIn')->with('path')->willReturn([$mount]);
2358
-
2359
-		self::invokePrivate($this->manager, 'pathCreateChecks', [$path]);
2360
-	}
2361
-
2362
-	public function testPathCreateChecksContainsNoSharedMount(): void {
2363
-		$path = $this->createMock(Folder::class);
2364
-		$path->method('getPath')->willReturn('path');
2352
+        $mount = $this->createMock(IMountPoint::class);
2353
+        $storage = $this->createMock(IStorage::class);
2354
+        $mount->method('getStorage')->willReturn($storage);
2355
+        $storage->method('instanceOfStorage')->with('\OCA\Files_Sharing\ISharedStorage')->willReturn(true);
2356
+
2357
+        $this->mountManager->method('findIn')->with('path')->willReturn([$mount]);
2358
+
2359
+        self::invokePrivate($this->manager, 'pathCreateChecks', [$path]);
2360
+    }
2361
+
2362
+    public function testPathCreateChecksContainsNoSharedMount(): void {
2363
+        $path = $this->createMock(Folder::class);
2364
+        $path->method('getPath')->willReturn('path');
2365 2365
 
2366
-		$mount = $this->createMock(IMountPoint::class);
2367
-		$storage = $this->createMock(IStorage::class);
2368
-		$mount->method('getStorage')->willReturn($storage);
2369
-		$storage->method('instanceOfStorage')->with('\OCA\Files_Sharing\ISharedStorage')->willReturn(false);
2370
-
2371
-		$this->mountManager->method('findIn')->with('path')->willReturn([$mount]);
2372
-
2373
-		self::invokePrivate($this->manager, 'pathCreateChecks', [$path]);
2374
-		$this->addToAssertionCount(1);
2375
-	}
2376
-
2377
-	public function testPathCreateChecksContainsNoFolder(): void {
2378
-		$path = $this->createMock(File::class);
2379
-
2380
-		self::invokePrivate($this->manager, 'pathCreateChecks', [$path]);
2381
-		$this->addToAssertionCount(1);
2382
-	}
2383
-
2384
-	public static function dataIsSharingDisabledForUser() {
2385
-		$data = [];
2386
-
2387
-		// No exclude groups
2388
-		$data[] = ['no', null, null, [], false];
2389
-
2390
-		// empty exclude / allow list, user no groups
2391
-		$data[] = ['yes', '', json_encode(['']), [], false];
2392
-		$data[] = ['allow', '', json_encode(['']), [], true];
2393
-
2394
-		// empty exclude / allow list, user groups
2395
-		$data[] = ['yes', '', json_encode(['']), ['group1', 'group2'], false];
2396
-		$data[] = ['allow', '', json_encode(['']), ['group1', 'group2'], true];
2397
-
2398
-		// Convert old list to json
2399
-		$data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), [], false];
2400
-		$data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), [], true];
2401
-
2402
-		// Old list partly groups in common
2403
-		$data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false];
2404
-		$data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false];
2405
-
2406
-		// Old list only groups in common
2407
-		$data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], true];
2408
-		$data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], false];
2409
-
2410
-		// New list partly in common
2411
-		$data[] = ['yes', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false];
2412
-		$data[] = ['allow', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false];
2413
-
2414
-		// New list only groups in common
2415
-		$data[] = ['yes', json_encode(['group1', 'group2']), null, ['group2'], true];
2416
-		$data[] = ['allow', json_encode(['group1', 'group2']), null, ['group2'], false];
2417
-
2418
-		return $data;
2419
-	}
2366
+        $mount = $this->createMock(IMountPoint::class);
2367
+        $storage = $this->createMock(IStorage::class);
2368
+        $mount->method('getStorage')->willReturn($storage);
2369
+        $storage->method('instanceOfStorage')->with('\OCA\Files_Sharing\ISharedStorage')->willReturn(false);
2370
+
2371
+        $this->mountManager->method('findIn')->with('path')->willReturn([$mount]);
2372
+
2373
+        self::invokePrivate($this->manager, 'pathCreateChecks', [$path]);
2374
+        $this->addToAssertionCount(1);
2375
+    }
2376
+
2377
+    public function testPathCreateChecksContainsNoFolder(): void {
2378
+        $path = $this->createMock(File::class);
2379
+
2380
+        self::invokePrivate($this->manager, 'pathCreateChecks', [$path]);
2381
+        $this->addToAssertionCount(1);
2382
+    }
2383
+
2384
+    public static function dataIsSharingDisabledForUser() {
2385
+        $data = [];
2386
+
2387
+        // No exclude groups
2388
+        $data[] = ['no', null, null, [], false];
2389
+
2390
+        // empty exclude / allow list, user no groups
2391
+        $data[] = ['yes', '', json_encode(['']), [], false];
2392
+        $data[] = ['allow', '', json_encode(['']), [], true];
2393
+
2394
+        // empty exclude / allow list, user groups
2395
+        $data[] = ['yes', '', json_encode(['']), ['group1', 'group2'], false];
2396
+        $data[] = ['allow', '', json_encode(['']), ['group1', 'group2'], true];
2397
+
2398
+        // Convert old list to json
2399
+        $data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), [], false];
2400
+        $data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), [], true];
2401
+
2402
+        // Old list partly groups in common
2403
+        $data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false];
2404
+        $data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false];
2405
+
2406
+        // Old list only groups in common
2407
+        $data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], true];
2408
+        $data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], false];
2409
+
2410
+        // New list partly in common
2411
+        $data[] = ['yes', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false];
2412
+        $data[] = ['allow', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false];
2413
+
2414
+        // New list only groups in common
2415
+        $data[] = ['yes', json_encode(['group1', 'group2']), null, ['group2'], true];
2416
+        $data[] = ['allow', json_encode(['group1', 'group2']), null, ['group2'], false];
2417
+
2418
+        return $data;
2419
+    }
2420 2420
 
2421
-	/**
2422
-	 *
2423
-	 * @param string $excludeGroups
2424
-	 * @param string $groupList
2425
-	 * @param string $setList
2426
-	 * @param string[] $groupIds
2427
-	 * @param bool $expected
2428
-	 */
2429
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataIsSharingDisabledForUser')]
2430
-	public function testIsSharingDisabledForUser($excludeGroups, $groupList, $setList, $groupIds, $expected): void {
2431
-		$user = $this->createMock(IUser::class);
2421
+    /**
2422
+     *
2423
+     * @param string $excludeGroups
2424
+     * @param string $groupList
2425
+     * @param string $setList
2426
+     * @param string[] $groupIds
2427
+     * @param bool $expected
2428
+     */
2429
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataIsSharingDisabledForUser')]
2430
+    public function testIsSharingDisabledForUser($excludeGroups, $groupList, $setList, $groupIds, $expected): void {
2431
+        $user = $this->createMock(IUser::class);
2432 2432
 
2433
-		$this->config->method('getAppValue')
2434
-			->willReturnMap([
2435
-				['core', 'shareapi_exclude_groups', 'no', $excludeGroups],
2436
-				['core', 'shareapi_exclude_groups_list', '', $groupList],
2437
-			]);
2433
+        $this->config->method('getAppValue')
2434
+            ->willReturnMap([
2435
+                ['core', 'shareapi_exclude_groups', 'no', $excludeGroups],
2436
+                ['core', 'shareapi_exclude_groups_list', '', $groupList],
2437
+            ]);
2438 2438
 
2439
-		if ($setList !== null) {
2440
-			$this->config->expects($this->once())
2441
-				->method('setAppValue')
2442
-				->with('core', 'shareapi_exclude_groups_list', $setList);
2443
-		} else {
2444
-			$this->config->expects($this->never())
2445
-				->method('setAppValue');
2446
-		}
2439
+        if ($setList !== null) {
2440
+            $this->config->expects($this->once())
2441
+                ->method('setAppValue')
2442
+                ->with('core', 'shareapi_exclude_groups_list', $setList);
2443
+        } else {
2444
+            $this->config->expects($this->never())
2445
+                ->method('setAppValue');
2446
+        }
2447 2447
 
2448
-		$this->groupManager->method('getUserGroupIds')
2449
-			->with($user)
2450
-			->willReturn($groupIds);
2448
+        $this->groupManager->method('getUserGroupIds')
2449
+            ->with($user)
2450
+            ->willReturn($groupIds);
2451 2451
 
2452
-		$this->userManager->method('get')->with('user')->willReturn($user);
2453
-
2454
-		$res = $this->manager->sharingDisabledForUser('user');
2455
-		$this->assertEquals($expected, $res);
2456
-	}
2457
-
2458
-	public static function dataCanShare() {
2459
-		$data = [];
2460
-
2461
-		/*
2452
+        $this->userManager->method('get')->with('user')->willReturn($user);
2453
+
2454
+        $res = $this->manager->sharingDisabledForUser('user');
2455
+        $this->assertEquals($expected, $res);
2456
+    }
2457
+
2458
+    public static function dataCanShare() {
2459
+        $data = [];
2460
+
2461
+        /*
2462 2462
 		 * [expected, sharing enabled, disabled for user]
2463 2463
 		 */
2464 2464
 
2465
-		$data[] = [false, 'no', false];
2466
-		$data[] = [false, 'no', true];
2467
-		$data[] = [true, 'yes', false];
2468
-		$data[] = [false, 'yes', true];
2469
-
2470
-		return $data;
2471
-	}
2472
-
2473
-	/**
2474
-	 *
2475
-	 * @param bool $expected
2476
-	 * @param string $sharingEnabled
2477
-	 * @param bool $disabledForUser
2478
-	 */
2479
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataCanShare')]
2480
-	public function testCanShare($expected, $sharingEnabled, $disabledForUser): void {
2481
-		$this->config->method('getAppValue')
2482
-			->willReturnMap([
2483
-				['core', 'shareapi_enabled', 'yes', $sharingEnabled],
2484
-			]);
2485
-
2486
-		$manager = $this->createManagerMock()
2487
-			->onlyMethods(['sharingDisabledForUser'])
2488
-			->getMock();
2489
-
2490
-		$manager->method('sharingDisabledForUser')
2491
-			->with('user')
2492
-			->willReturn($disabledForUser);
2493
-
2494
-		$share = $this->manager->newShare();
2495
-		$share->setSharedBy('user');
2496
-
2497
-		$exception = false;
2498
-		try {
2499
-			$res = self::invokePrivate($manager, 'canShare', [$share]);
2500
-		} catch (\Exception $e) {
2501
-			$exception = true;
2502
-		}
2503
-
2504
-		$this->assertEquals($expected, !$exception);
2505
-	}
2506
-
2507
-	public function testCreateShareUser(): void {
2508
-		/** @var Manager&MockObject $manager */
2509
-		$manager = $this->createManagerMock()
2510
-			->onlyMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks'])
2511
-			->getMock();
2512
-
2513
-		$shareOwner = $this->createMock(IUser::class);
2514
-		$shareOwner->method('getUID')->willReturn('shareOwner');
2515
-
2516
-		$storage = $this->createMock(IStorage::class);
2517
-		$path = $this->createMock(File::class);
2518
-		$path->method('getOwner')->willReturn($shareOwner);
2519
-		$path->method('getName')->willReturn('target');
2520
-		$path->method('getStorage')->willReturn($storage);
2521
-
2522
-		$share = $this->createShare(
2523
-			null,
2524
-			IShare::TYPE_USER,
2525
-			$path,
2526
-			'sharedWith',
2527
-			'sharedBy',
2528
-			null,
2529
-			Constants::PERMISSION_ALL);
2530
-
2531
-		$manager->expects($this->once())
2532
-			->method('canShare')
2533
-			->with($share)
2534
-			->willReturn(true);
2535
-		$manager->expects($this->once())
2536
-			->method('generalCreateChecks')
2537
-			->with($share);
2538
-		;
2539
-		$manager->expects($this->once())
2540
-			->method('userCreateChecks')
2541
-			->with($share);
2542
-		;
2543
-		$manager->expects($this->once())
2544
-			->method('pathCreateChecks')
2545
-			->with($path);
2546
-
2547
-		$this->defaultProvider
2548
-			->expects($this->once())
2549
-			->method('create')
2550
-			->with($share)
2551
-			->willReturnArgument(0);
2552
-
2553
-		$share->expects($this->once())
2554
-			->method('setShareOwner')
2555
-			->with('shareOwner');
2556
-		$share->expects($this->once())
2557
-			->method('setTarget')
2558
-			->with('/target');
2559
-
2560
-		$manager->createShare($share);
2561
-	}
2562
-
2563
-	public function testCreateShareGroup(): void {
2564
-		$manager = $this->createManagerMock()
2565
-			->onlyMethods(['canShare', 'generalCreateChecks', 'groupCreateChecks', 'pathCreateChecks'])
2566
-			->getMock();
2567
-
2568
-		$shareOwner = $this->createMock(IUser::class);
2569
-		$shareOwner->method('getUID')->willReturn('shareOwner');
2570
-
2571
-		$storage = $this->createMock(IStorage::class);
2572
-		$path = $this->createMock(File::class);
2573
-		$path->method('getOwner')->willReturn($shareOwner);
2574
-		$path->method('getName')->willReturn('target');
2575
-		$path->method('getStorage')->willReturn($storage);
2576
-
2577
-		$share = $this->createShare(
2578
-			null,
2579
-			IShare::TYPE_GROUP,
2580
-			$path,
2581
-			'sharedWith',
2582
-			'sharedBy',
2583
-			null,
2584
-			Constants::PERMISSION_ALL);
2585
-
2586
-		$manager->expects($this->once())
2587
-			->method('canShare')
2588
-			->with($share)
2589
-			->willReturn(true);
2590
-		$manager->expects($this->once())
2591
-			->method('generalCreateChecks')
2592
-			->with($share);
2593
-		;
2594
-		$manager->expects($this->once())
2595
-			->method('groupCreateChecks')
2596
-			->with($share);
2597
-		;
2598
-		$manager->expects($this->once())
2599
-			->method('pathCreateChecks')
2600
-			->with($path);
2601
-
2602
-		$this->defaultProvider
2603
-			->expects($this->once())
2604
-			->method('create')
2605
-			->with($share)
2606
-			->willReturnArgument(0);
2607
-
2608
-		$share->expects($this->once())
2609
-			->method('setShareOwner')
2610
-			->with('shareOwner');
2611
-		$share->expects($this->once())
2612
-			->method('setTarget')
2613
-			->with('/target');
2614
-
2615
-		$manager->createShare($share);
2616
-	}
2617
-
2618
-	public function testCreateShareLink(): void {
2619
-		$manager = $this->createManagerMock()
2620
-			->onlyMethods([
2621
-				'canShare',
2622
-				'generalCreateChecks',
2623
-				'linkCreateChecks',
2624
-				'pathCreateChecks',
2625
-				'validateExpirationDateLink',
2626
-				'verifyPassword',
2627
-				'setLinkParent',
2628
-			])
2629
-			->getMock();
2630
-
2631
-		$shareOwner = $this->createMock(IUser::class);
2632
-		$shareOwner->method('getUID')->willReturn('shareOwner');
2633
-
2634
-		$storage = $this->createMock(IStorage::class);
2635
-		$path = $this->createMock(File::class);
2636
-		$path->method('getOwner')->willReturn($shareOwner);
2637
-		$path->method('getName')->willReturn('target');
2638
-		$path->method('getId')->willReturn(1);
2639
-		$path->method('getStorage')->willReturn($storage);
2640
-
2641
-		$date = new \DateTime();
2642
-
2643
-		$share = $this->manager->newShare();
2644
-		$share->setShareType(IShare::TYPE_LINK)
2645
-			->setNode($path)
2646
-			->setSharedBy('sharedBy')
2647
-			->setPermissions(Constants::PERMISSION_ALL)
2648
-			->setExpirationDate($date)
2649
-			->setPassword('password');
2650
-
2651
-		$manager->expects($this->once())
2652
-			->method('canShare')
2653
-			->with($share)
2654
-			->willReturn(true);
2655
-		$manager->expects($this->once())
2656
-			->method('generalCreateChecks')
2657
-			->with($share);
2658
-		;
2659
-		$manager->expects($this->once())
2660
-			->method('linkCreateChecks')
2661
-			->with($share);
2662
-		;
2663
-		$manager->expects($this->once())
2664
-			->method('pathCreateChecks')
2665
-			->with($path);
2666
-		$manager->expects($this->once())
2667
-			->method('validateExpirationDateLink')
2668
-			->with($share)
2669
-			->willReturn($share);
2670
-		$manager->expects($this->once())
2671
-			->method('verifyPassword')
2672
-			->with('password');
2673
-		$manager->expects($this->once())
2674
-			->method('setLinkParent')
2675
-			->with($share);
2676
-
2677
-		$this->hasher->expects($this->once())
2678
-			->method('hash')
2679
-			->with('password')
2680
-			->willReturn('hashed');
2681
-
2682
-		$this->secureRandom->method('generate')
2683
-			->willReturn('token');
2684
-
2685
-		$this->defaultProvider
2686
-			->expects($this->once())
2687
-			->method('create')
2688
-			->with($share)
2689
-			->willReturnCallback(function (Share $share) {
2690
-				return $share->setId(42);
2691
-			});
2692
-
2693
-		$calls = [
2694
-			BeforeShareCreatedEvent::class,
2695
-			ShareCreatedEvent::class,
2696
-		];
2697
-		$this->dispatcher->expects($this->exactly(2))
2698
-			->method('dispatchTyped')
2699
-			->willReturnCallback(function ($event) use (&$calls, $date, $path): void {
2700
-				$expected = array_shift($calls);
2701
-				$this->assertInstanceOf($expected, $event);
2702
-				$share = $event->getShare();
2703
-
2704
-				$this->assertEquals(IShare::TYPE_LINK, $share->getShareType(), 'getShareType');
2705
-				$this->assertEquals($path, $share->getNode(), 'getNode');
2706
-				$this->assertEquals('sharedBy', $share->getSharedBy(), 'getSharedBy');
2707
-				$this->assertEquals(Constants::PERMISSION_ALL, $share->getPermissions(), 'getPermissions');
2708
-				$this->assertEquals($date, $share->getExpirationDate(), 'getExpirationDate');
2709
-				$this->assertEquals('hashed', $share->getPassword(), 'getPassword');
2710
-				$this->assertEquals('token', $share->getToken(), 'getToken');
2711
-
2712
-				if ($expected === ShareCreatedEvent::class) {
2713
-					$this->assertEquals('42', $share->getId(), 'getId');
2714
-					$this->assertEquals('/target', $share->getTarget(), 'getTarget');
2715
-				}
2716
-			});
2717
-
2718
-		/** @var IShare $share */
2719
-		$share = $manager->createShare($share);
2720
-
2721
-		$this->assertSame('shareOwner', $share->getShareOwner());
2722
-		$this->assertEquals('/target', $share->getTarget());
2723
-		$this->assertSame($date, $share->getExpirationDate());
2724
-		$this->assertEquals('token', $share->getToken());
2725
-		$this->assertEquals('hashed', $share->getPassword());
2726
-	}
2727
-
2728
-	public function testCreateShareMail(): void {
2729
-		$manager = $this->createManagerMock()
2730
-			->onlyMethods([
2731
-				'canShare',
2732
-				'generalCreateChecks',
2733
-				'linkCreateChecks',
2734
-				'pathCreateChecks',
2735
-				'validateExpirationDateLink',
2736
-				'verifyPassword',
2737
-				'setLinkParent',
2738
-			])
2739
-			->getMock();
2740
-
2741
-		$shareOwner = $this->createMock(IUser::class);
2742
-		$shareOwner->method('getUID')->willReturn('shareOwner');
2743
-
2744
-		$storage = $this->createMock(IStorage::class);
2745
-		$path = $this->createMock(File::class);
2746
-		$path->method('getOwner')->willReturn($shareOwner);
2747
-		$path->method('getName')->willReturn('target');
2748
-		$path->method('getId')->willReturn(1);
2749
-		$path->method('getStorage')->willReturn($storage);
2750
-
2751
-		$share = $this->manager->newShare();
2752
-		$share->setShareType(IShare::TYPE_EMAIL)
2753
-			->setNode($path)
2754
-			->setSharedBy('sharedBy')
2755
-			->setPermissions(Constants::PERMISSION_ALL);
2756
-
2757
-		$manager->expects($this->once())
2758
-			->method('canShare')
2759
-			->with($share)
2760
-			->willReturn(true);
2761
-		$manager->expects($this->once())
2762
-			->method('generalCreateChecks')
2763
-			->with($share);
2764
-
2765
-		$manager->expects($this->once())
2766
-			->method('linkCreateChecks');
2767
-		$manager->expects($this->once())
2768
-			->method('pathCreateChecks')
2769
-			->with($path);
2770
-		$manager->expects($this->once())
2771
-			->method('validateExpirationDateLink')
2772
-			->with($share)
2773
-			->willReturn($share);
2774
-		$manager->expects($this->once())
2775
-			->method('verifyPassword');
2776
-		$manager->expects($this->once())
2777
-			->method('setLinkParent');
2778
-
2779
-		$this->secureRandom->method('generate')
2780
-			->willReturn('token');
2781
-
2782
-		$this->defaultProvider
2783
-			->expects($this->once())
2784
-			->method('create')
2785
-			->with($share)
2786
-			->willReturnCallback(function (Share $share) {
2787
-				return $share->setId(42);
2788
-			});
2789
-
2790
-		$calls = [
2791
-			BeforeShareCreatedEvent::class,
2792
-			ShareCreatedEvent::class,
2793
-		];
2794
-		$this->dispatcher->expects($this->exactly(2))
2795
-			->method('dispatchTyped')
2796
-			->willReturnCallback(function ($event) use (&$calls, $path): void {
2797
-				$expected = array_shift($calls);
2798
-				$this->assertInstanceOf($expected, $event);
2799
-				$share = $event->getShare();
2800
-
2801
-				$this->assertEquals(IShare::TYPE_EMAIL, $share->getShareType(), 'getShareType');
2802
-				$this->assertEquals($path, $share->getNode(), 'getNode');
2803
-				$this->assertEquals('sharedBy', $share->getSharedBy(), 'getSharedBy');
2804
-				$this->assertEquals(Constants::PERMISSION_ALL, $share->getPermissions(), 'getPermissions');
2805
-				$this->assertNull($share->getExpirationDate(), 'getExpirationDate');
2806
-				$this->assertNull($share->getPassword(), 'getPassword');
2807
-				$this->assertEquals('token', $share->getToken(), 'getToken');
2808
-
2809
-				if ($expected === ShareCreatedEvent::class) {
2810
-					$this->assertEquals('42', $share->getId(), 'getId');
2811
-					$this->assertEquals('/target', $share->getTarget(), 'getTarget');
2812
-				}
2813
-			});
2814
-
2815
-		/** @var IShare $share */
2816
-		$share = $manager->createShare($share);
2817
-
2818
-		$this->assertSame('shareOwner', $share->getShareOwner());
2819
-		$this->assertEquals('/target', $share->getTarget());
2820
-		$this->assertEquals('token', $share->getToken());
2821
-	}
2822
-
2823
-
2824
-	public function testCreateShareHookError(): void {
2825
-		$this->expectException(\Exception::class);
2826
-		$this->expectExceptionMessage('I won\'t let you share');
2827
-
2828
-		$manager = $this->createManagerMock()
2829
-			->onlyMethods([
2830
-				'canShare',
2831
-				'generalCreateChecks',
2832
-				'userCreateChecks',
2833
-				'pathCreateChecks',
2834
-			])
2835
-			->getMock();
2836
-
2837
-		$shareOwner = $this->createMock(IUser::class);
2838
-		$shareOwner->method('getUID')->willReturn('shareOwner');
2839
-
2840
-		$storage = $this->createMock(IStorage::class);
2841
-		$path = $this->createMock(File::class);
2842
-		$path->method('getOwner')->willReturn($shareOwner);
2843
-		$path->method('getName')->willReturn('target');
2844
-		$path->method('getStorage')->willReturn($storage);
2845
-
2846
-		$share = $this->createShare(
2847
-			null,
2848
-			IShare::TYPE_USER,
2849
-			$path,
2850
-			'sharedWith',
2851
-			'sharedBy',
2852
-			null,
2853
-			Constants::PERMISSION_ALL);
2854
-
2855
-		$manager->expects($this->once())
2856
-			->method('canShare')
2857
-			->with($share)
2858
-			->willReturn(true);
2859
-		$manager->expects($this->once())
2860
-			->method('generalCreateChecks')
2861
-			->with($share);
2862
-		;
2863
-		$manager->expects($this->once())
2864
-			->method('userCreateChecks')
2865
-			->with($share);
2866
-		;
2867
-		$manager->expects($this->once())
2868
-			->method('pathCreateChecks')
2869
-			->with($path);
2870
-
2871
-		$share->expects($this->once())
2872
-			->method('setShareOwner')
2873
-			->with('shareOwner');
2874
-		$share->expects($this->once())
2875
-			->method('setTarget')
2876
-			->with('/target');
2877
-
2878
-		// Pre share
2879
-		$this->dispatcher->expects($this->once())
2880
-			->method('dispatchTyped')
2881
-			->with(
2882
-				$this->isInstanceOf(BeforeShareCreatedEvent::class)
2883
-			)->willReturnCallback(function (BeforeShareCreatedEvent $e): void {
2884
-				$e->setError('I won\'t let you share!');
2885
-				$e->stopPropagation();
2886
-			}
2887
-			);
2888
-
2889
-		$manager->createShare($share);
2890
-	}
2891
-
2892
-	public function testCreateShareOfIncomingFederatedShare(): void {
2893
-		$manager = $this->createManagerMock()
2894
-			->onlyMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks'])
2895
-			->getMock();
2896
-
2897
-		$shareOwner = $this->createMock(IUser::class);
2898
-		$shareOwner->method('getUID')->willReturn('shareOwner');
2899
-
2900
-		$storage = $this->createMock(IStorage::class);
2901
-		$storage->method('instanceOfStorage')
2902
-			->with('OCA\Files_Sharing\External\Storage')
2903
-			->willReturn(true);
2904
-
2905
-		$storage2 = $this->createMock(IStorage::class);
2906
-		$storage2->method('instanceOfStorage')
2907
-			->with('OCA\Files_Sharing\External\Storage')
2908
-			->willReturn(false);
2909
-
2910
-		$path = $this->createMock(File::class);
2911
-		$path->expects($this->never())->method('getOwner');
2912
-		$path->method('getName')->willReturn('target');
2913
-		$path->method('getStorage')->willReturn($storage);
2914
-
2915
-		$parent = $this->createMock(Folder::class);
2916
-		$parent->method('getStorage')->willReturn($storage);
2917
-
2918
-		$parentParent = $this->createMock(Folder::class);
2919
-		$parentParent->method('getStorage')->willReturn($storage2);
2920
-		$parentParent->method('getOwner')->willReturn($shareOwner);
2921
-
2922
-		$path->method('getParent')->willReturn($parent);
2923
-		$parent->method('getParent')->willReturn($parentParent);
2924
-
2925
-		$share = $this->createShare(
2926
-			null,
2927
-			IShare::TYPE_USER,
2928
-			$path,
2929
-			'sharedWith',
2930
-			'sharedBy',
2931
-			null,
2932
-			Constants::PERMISSION_ALL);
2933
-
2934
-		$manager->expects($this->once())
2935
-			->method('canShare')
2936
-			->with($share)
2937
-			->willReturn(true);
2938
-		$manager->expects($this->once())
2939
-			->method('generalCreateChecks')
2940
-			->with($share);
2941
-		;
2942
-		$manager->expects($this->once())
2943
-			->method('userCreateChecks')
2944
-			->with($share);
2945
-		;
2946
-		$manager->expects($this->once())
2947
-			->method('pathCreateChecks')
2948
-			->with($path);
2949
-
2950
-		$this->defaultProvider
2951
-			->expects($this->once())
2952
-			->method('create')
2953
-			->with($share)
2954
-			->willReturnArgument(0);
2955
-
2956
-		$share->expects($this->once())
2957
-			->method('setShareOwner')
2958
-			->with('shareOwner');
2959
-		$share->expects($this->once())
2960
-			->method('setTarget')
2961
-			->with('/target');
2962
-
2963
-		$manager->createShare($share);
2964
-	}
2965
-
2966
-	public function testGetSharesBy(): void {
2967
-		$share = $this->manager->newShare();
2968
-
2969
-		$node = $this->createMock(Folder::class);
2970
-
2971
-		$this->defaultProvider->expects($this->once())
2972
-			->method('getSharesBy')
2973
-			->with(
2974
-				$this->equalTo('user'),
2975
-				$this->equalTo(IShare::TYPE_USER),
2976
-				$this->equalTo($node),
2977
-				$this->equalTo(true),
2978
-				$this->equalTo(1),
2979
-				$this->equalTo(1)
2980
-			)->willReturn([$share]);
2981
-
2982
-		$shares = $this->manager->getSharesBy('user', IShare::TYPE_USER, $node, true, 1, 1);
2983
-
2984
-		$this->assertCount(1, $shares);
2985
-		$this->assertSame($share, $shares[0]);
2986
-	}
2987
-
2988
-	public function testGetSharesByOwnerless(): void {
2989
-		$mount = $this->createMock(IShareOwnerlessMount::class);
2990
-
2991
-		$node = $this->createMock(Folder::class);
2992
-		$node
2993
-			->expects($this->once())
2994
-			->method('getMountPoint')
2995
-			->willReturn($mount);
2996
-
2997
-		$share = $this->manager->newShare();
2998
-		$share->setNode($node);
2999
-		$share->setShareType(IShare::TYPE_USER);
3000
-
3001
-		$this->defaultProvider
3002
-			->expects($this->once())
3003
-			->method('getSharesByPath')
3004
-			->with($this->equalTo($node))
3005
-			->willReturn([$share]);
3006
-
3007
-		$shares = $this->manager->getSharesBy('user', IShare::TYPE_USER, $node, true, 1, 1);
3008
-
3009
-		$this->assertCount(1, $shares);
3010
-		$this->assertSame($share, $shares[0]);
3011
-	}
3012
-
3013
-	/**
3014
-	 * Test to ensure we correctly remove expired link shares
3015
-	 *
3016
-	 * We have 8 Shares and we want the 3 first valid shares.
3017
-	 * share 3-6 and 8 are expired. Thus at the end of this test we should
3018
-	 * have received share 1,2 and 7. And from the manager. Share 3-6 should be
3019
-	 * deleted (as they are evaluated). but share 8 should still be there.
3020
-	 */
3021
-	public function testGetSharesByExpiredLinkShares(): void {
3022
-		$manager = $this->createManagerMock()
3023
-			->onlyMethods(['deleteShare'])
3024
-			->getMock();
3025
-
3026
-		/** @var IShare[] $shares */
3027
-		$shares = [];
3028
-
3029
-		/*
2465
+        $data[] = [false, 'no', false];
2466
+        $data[] = [false, 'no', true];
2467
+        $data[] = [true, 'yes', false];
2468
+        $data[] = [false, 'yes', true];
2469
+
2470
+        return $data;
2471
+    }
2472
+
2473
+    /**
2474
+     *
2475
+     * @param bool $expected
2476
+     * @param string $sharingEnabled
2477
+     * @param bool $disabledForUser
2478
+     */
2479
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataCanShare')]
2480
+    public function testCanShare($expected, $sharingEnabled, $disabledForUser): void {
2481
+        $this->config->method('getAppValue')
2482
+            ->willReturnMap([
2483
+                ['core', 'shareapi_enabled', 'yes', $sharingEnabled],
2484
+            ]);
2485
+
2486
+        $manager = $this->createManagerMock()
2487
+            ->onlyMethods(['sharingDisabledForUser'])
2488
+            ->getMock();
2489
+
2490
+        $manager->method('sharingDisabledForUser')
2491
+            ->with('user')
2492
+            ->willReturn($disabledForUser);
2493
+
2494
+        $share = $this->manager->newShare();
2495
+        $share->setSharedBy('user');
2496
+
2497
+        $exception = false;
2498
+        try {
2499
+            $res = self::invokePrivate($manager, 'canShare', [$share]);
2500
+        } catch (\Exception $e) {
2501
+            $exception = true;
2502
+        }
2503
+
2504
+        $this->assertEquals($expected, !$exception);
2505
+    }
2506
+
2507
+    public function testCreateShareUser(): void {
2508
+        /** @var Manager&MockObject $manager */
2509
+        $manager = $this->createManagerMock()
2510
+            ->onlyMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks'])
2511
+            ->getMock();
2512
+
2513
+        $shareOwner = $this->createMock(IUser::class);
2514
+        $shareOwner->method('getUID')->willReturn('shareOwner');
2515
+
2516
+        $storage = $this->createMock(IStorage::class);
2517
+        $path = $this->createMock(File::class);
2518
+        $path->method('getOwner')->willReturn($shareOwner);
2519
+        $path->method('getName')->willReturn('target');
2520
+        $path->method('getStorage')->willReturn($storage);
2521
+
2522
+        $share = $this->createShare(
2523
+            null,
2524
+            IShare::TYPE_USER,
2525
+            $path,
2526
+            'sharedWith',
2527
+            'sharedBy',
2528
+            null,
2529
+            Constants::PERMISSION_ALL);
2530
+
2531
+        $manager->expects($this->once())
2532
+            ->method('canShare')
2533
+            ->with($share)
2534
+            ->willReturn(true);
2535
+        $manager->expects($this->once())
2536
+            ->method('generalCreateChecks')
2537
+            ->with($share);
2538
+        ;
2539
+        $manager->expects($this->once())
2540
+            ->method('userCreateChecks')
2541
+            ->with($share);
2542
+        ;
2543
+        $manager->expects($this->once())
2544
+            ->method('pathCreateChecks')
2545
+            ->with($path);
2546
+
2547
+        $this->defaultProvider
2548
+            ->expects($this->once())
2549
+            ->method('create')
2550
+            ->with($share)
2551
+            ->willReturnArgument(0);
2552
+
2553
+        $share->expects($this->once())
2554
+            ->method('setShareOwner')
2555
+            ->with('shareOwner');
2556
+        $share->expects($this->once())
2557
+            ->method('setTarget')
2558
+            ->with('/target');
2559
+
2560
+        $manager->createShare($share);
2561
+    }
2562
+
2563
+    public function testCreateShareGroup(): void {
2564
+        $manager = $this->createManagerMock()
2565
+            ->onlyMethods(['canShare', 'generalCreateChecks', 'groupCreateChecks', 'pathCreateChecks'])
2566
+            ->getMock();
2567
+
2568
+        $shareOwner = $this->createMock(IUser::class);
2569
+        $shareOwner->method('getUID')->willReturn('shareOwner');
2570
+
2571
+        $storage = $this->createMock(IStorage::class);
2572
+        $path = $this->createMock(File::class);
2573
+        $path->method('getOwner')->willReturn($shareOwner);
2574
+        $path->method('getName')->willReturn('target');
2575
+        $path->method('getStorage')->willReturn($storage);
2576
+
2577
+        $share = $this->createShare(
2578
+            null,
2579
+            IShare::TYPE_GROUP,
2580
+            $path,
2581
+            'sharedWith',
2582
+            'sharedBy',
2583
+            null,
2584
+            Constants::PERMISSION_ALL);
2585
+
2586
+        $manager->expects($this->once())
2587
+            ->method('canShare')
2588
+            ->with($share)
2589
+            ->willReturn(true);
2590
+        $manager->expects($this->once())
2591
+            ->method('generalCreateChecks')
2592
+            ->with($share);
2593
+        ;
2594
+        $manager->expects($this->once())
2595
+            ->method('groupCreateChecks')
2596
+            ->with($share);
2597
+        ;
2598
+        $manager->expects($this->once())
2599
+            ->method('pathCreateChecks')
2600
+            ->with($path);
2601
+
2602
+        $this->defaultProvider
2603
+            ->expects($this->once())
2604
+            ->method('create')
2605
+            ->with($share)
2606
+            ->willReturnArgument(0);
2607
+
2608
+        $share->expects($this->once())
2609
+            ->method('setShareOwner')
2610
+            ->with('shareOwner');
2611
+        $share->expects($this->once())
2612
+            ->method('setTarget')
2613
+            ->with('/target');
2614
+
2615
+        $manager->createShare($share);
2616
+    }
2617
+
2618
+    public function testCreateShareLink(): void {
2619
+        $manager = $this->createManagerMock()
2620
+            ->onlyMethods([
2621
+                'canShare',
2622
+                'generalCreateChecks',
2623
+                'linkCreateChecks',
2624
+                'pathCreateChecks',
2625
+                'validateExpirationDateLink',
2626
+                'verifyPassword',
2627
+                'setLinkParent',
2628
+            ])
2629
+            ->getMock();
2630
+
2631
+        $shareOwner = $this->createMock(IUser::class);
2632
+        $shareOwner->method('getUID')->willReturn('shareOwner');
2633
+
2634
+        $storage = $this->createMock(IStorage::class);
2635
+        $path = $this->createMock(File::class);
2636
+        $path->method('getOwner')->willReturn($shareOwner);
2637
+        $path->method('getName')->willReturn('target');
2638
+        $path->method('getId')->willReturn(1);
2639
+        $path->method('getStorage')->willReturn($storage);
2640
+
2641
+        $date = new \DateTime();
2642
+
2643
+        $share = $this->manager->newShare();
2644
+        $share->setShareType(IShare::TYPE_LINK)
2645
+            ->setNode($path)
2646
+            ->setSharedBy('sharedBy')
2647
+            ->setPermissions(Constants::PERMISSION_ALL)
2648
+            ->setExpirationDate($date)
2649
+            ->setPassword('password');
2650
+
2651
+        $manager->expects($this->once())
2652
+            ->method('canShare')
2653
+            ->with($share)
2654
+            ->willReturn(true);
2655
+        $manager->expects($this->once())
2656
+            ->method('generalCreateChecks')
2657
+            ->with($share);
2658
+        ;
2659
+        $manager->expects($this->once())
2660
+            ->method('linkCreateChecks')
2661
+            ->with($share);
2662
+        ;
2663
+        $manager->expects($this->once())
2664
+            ->method('pathCreateChecks')
2665
+            ->with($path);
2666
+        $manager->expects($this->once())
2667
+            ->method('validateExpirationDateLink')
2668
+            ->with($share)
2669
+            ->willReturn($share);
2670
+        $manager->expects($this->once())
2671
+            ->method('verifyPassword')
2672
+            ->with('password');
2673
+        $manager->expects($this->once())
2674
+            ->method('setLinkParent')
2675
+            ->with($share);
2676
+
2677
+        $this->hasher->expects($this->once())
2678
+            ->method('hash')
2679
+            ->with('password')
2680
+            ->willReturn('hashed');
2681
+
2682
+        $this->secureRandom->method('generate')
2683
+            ->willReturn('token');
2684
+
2685
+        $this->defaultProvider
2686
+            ->expects($this->once())
2687
+            ->method('create')
2688
+            ->with($share)
2689
+            ->willReturnCallback(function (Share $share) {
2690
+                return $share->setId(42);
2691
+            });
2692
+
2693
+        $calls = [
2694
+            BeforeShareCreatedEvent::class,
2695
+            ShareCreatedEvent::class,
2696
+        ];
2697
+        $this->dispatcher->expects($this->exactly(2))
2698
+            ->method('dispatchTyped')
2699
+            ->willReturnCallback(function ($event) use (&$calls, $date, $path): void {
2700
+                $expected = array_shift($calls);
2701
+                $this->assertInstanceOf($expected, $event);
2702
+                $share = $event->getShare();
2703
+
2704
+                $this->assertEquals(IShare::TYPE_LINK, $share->getShareType(), 'getShareType');
2705
+                $this->assertEquals($path, $share->getNode(), 'getNode');
2706
+                $this->assertEquals('sharedBy', $share->getSharedBy(), 'getSharedBy');
2707
+                $this->assertEquals(Constants::PERMISSION_ALL, $share->getPermissions(), 'getPermissions');
2708
+                $this->assertEquals($date, $share->getExpirationDate(), 'getExpirationDate');
2709
+                $this->assertEquals('hashed', $share->getPassword(), 'getPassword');
2710
+                $this->assertEquals('token', $share->getToken(), 'getToken');
2711
+
2712
+                if ($expected === ShareCreatedEvent::class) {
2713
+                    $this->assertEquals('42', $share->getId(), 'getId');
2714
+                    $this->assertEquals('/target', $share->getTarget(), 'getTarget');
2715
+                }
2716
+            });
2717
+
2718
+        /** @var IShare $share */
2719
+        $share = $manager->createShare($share);
2720
+
2721
+        $this->assertSame('shareOwner', $share->getShareOwner());
2722
+        $this->assertEquals('/target', $share->getTarget());
2723
+        $this->assertSame($date, $share->getExpirationDate());
2724
+        $this->assertEquals('token', $share->getToken());
2725
+        $this->assertEquals('hashed', $share->getPassword());
2726
+    }
2727
+
2728
+    public function testCreateShareMail(): void {
2729
+        $manager = $this->createManagerMock()
2730
+            ->onlyMethods([
2731
+                'canShare',
2732
+                'generalCreateChecks',
2733
+                'linkCreateChecks',
2734
+                'pathCreateChecks',
2735
+                'validateExpirationDateLink',
2736
+                'verifyPassword',
2737
+                'setLinkParent',
2738
+            ])
2739
+            ->getMock();
2740
+
2741
+        $shareOwner = $this->createMock(IUser::class);
2742
+        $shareOwner->method('getUID')->willReturn('shareOwner');
2743
+
2744
+        $storage = $this->createMock(IStorage::class);
2745
+        $path = $this->createMock(File::class);
2746
+        $path->method('getOwner')->willReturn($shareOwner);
2747
+        $path->method('getName')->willReturn('target');
2748
+        $path->method('getId')->willReturn(1);
2749
+        $path->method('getStorage')->willReturn($storage);
2750
+
2751
+        $share = $this->manager->newShare();
2752
+        $share->setShareType(IShare::TYPE_EMAIL)
2753
+            ->setNode($path)
2754
+            ->setSharedBy('sharedBy')
2755
+            ->setPermissions(Constants::PERMISSION_ALL);
2756
+
2757
+        $manager->expects($this->once())
2758
+            ->method('canShare')
2759
+            ->with($share)
2760
+            ->willReturn(true);
2761
+        $manager->expects($this->once())
2762
+            ->method('generalCreateChecks')
2763
+            ->with($share);
2764
+
2765
+        $manager->expects($this->once())
2766
+            ->method('linkCreateChecks');
2767
+        $manager->expects($this->once())
2768
+            ->method('pathCreateChecks')
2769
+            ->with($path);
2770
+        $manager->expects($this->once())
2771
+            ->method('validateExpirationDateLink')
2772
+            ->with($share)
2773
+            ->willReturn($share);
2774
+        $manager->expects($this->once())
2775
+            ->method('verifyPassword');
2776
+        $manager->expects($this->once())
2777
+            ->method('setLinkParent');
2778
+
2779
+        $this->secureRandom->method('generate')
2780
+            ->willReturn('token');
2781
+
2782
+        $this->defaultProvider
2783
+            ->expects($this->once())
2784
+            ->method('create')
2785
+            ->with($share)
2786
+            ->willReturnCallback(function (Share $share) {
2787
+                return $share->setId(42);
2788
+            });
2789
+
2790
+        $calls = [
2791
+            BeforeShareCreatedEvent::class,
2792
+            ShareCreatedEvent::class,
2793
+        ];
2794
+        $this->dispatcher->expects($this->exactly(2))
2795
+            ->method('dispatchTyped')
2796
+            ->willReturnCallback(function ($event) use (&$calls, $path): void {
2797
+                $expected = array_shift($calls);
2798
+                $this->assertInstanceOf($expected, $event);
2799
+                $share = $event->getShare();
2800
+
2801
+                $this->assertEquals(IShare::TYPE_EMAIL, $share->getShareType(), 'getShareType');
2802
+                $this->assertEquals($path, $share->getNode(), 'getNode');
2803
+                $this->assertEquals('sharedBy', $share->getSharedBy(), 'getSharedBy');
2804
+                $this->assertEquals(Constants::PERMISSION_ALL, $share->getPermissions(), 'getPermissions');
2805
+                $this->assertNull($share->getExpirationDate(), 'getExpirationDate');
2806
+                $this->assertNull($share->getPassword(), 'getPassword');
2807
+                $this->assertEquals('token', $share->getToken(), 'getToken');
2808
+
2809
+                if ($expected === ShareCreatedEvent::class) {
2810
+                    $this->assertEquals('42', $share->getId(), 'getId');
2811
+                    $this->assertEquals('/target', $share->getTarget(), 'getTarget');
2812
+                }
2813
+            });
2814
+
2815
+        /** @var IShare $share */
2816
+        $share = $manager->createShare($share);
2817
+
2818
+        $this->assertSame('shareOwner', $share->getShareOwner());
2819
+        $this->assertEquals('/target', $share->getTarget());
2820
+        $this->assertEquals('token', $share->getToken());
2821
+    }
2822
+
2823
+
2824
+    public function testCreateShareHookError(): void {
2825
+        $this->expectException(\Exception::class);
2826
+        $this->expectExceptionMessage('I won\'t let you share');
2827
+
2828
+        $manager = $this->createManagerMock()
2829
+            ->onlyMethods([
2830
+                'canShare',
2831
+                'generalCreateChecks',
2832
+                'userCreateChecks',
2833
+                'pathCreateChecks',
2834
+            ])
2835
+            ->getMock();
2836
+
2837
+        $shareOwner = $this->createMock(IUser::class);
2838
+        $shareOwner->method('getUID')->willReturn('shareOwner');
2839
+
2840
+        $storage = $this->createMock(IStorage::class);
2841
+        $path = $this->createMock(File::class);
2842
+        $path->method('getOwner')->willReturn($shareOwner);
2843
+        $path->method('getName')->willReturn('target');
2844
+        $path->method('getStorage')->willReturn($storage);
2845
+
2846
+        $share = $this->createShare(
2847
+            null,
2848
+            IShare::TYPE_USER,
2849
+            $path,
2850
+            'sharedWith',
2851
+            'sharedBy',
2852
+            null,
2853
+            Constants::PERMISSION_ALL);
2854
+
2855
+        $manager->expects($this->once())
2856
+            ->method('canShare')
2857
+            ->with($share)
2858
+            ->willReturn(true);
2859
+        $manager->expects($this->once())
2860
+            ->method('generalCreateChecks')
2861
+            ->with($share);
2862
+        ;
2863
+        $manager->expects($this->once())
2864
+            ->method('userCreateChecks')
2865
+            ->with($share);
2866
+        ;
2867
+        $manager->expects($this->once())
2868
+            ->method('pathCreateChecks')
2869
+            ->with($path);
2870
+
2871
+        $share->expects($this->once())
2872
+            ->method('setShareOwner')
2873
+            ->with('shareOwner');
2874
+        $share->expects($this->once())
2875
+            ->method('setTarget')
2876
+            ->with('/target');
2877
+
2878
+        // Pre share
2879
+        $this->dispatcher->expects($this->once())
2880
+            ->method('dispatchTyped')
2881
+            ->with(
2882
+                $this->isInstanceOf(BeforeShareCreatedEvent::class)
2883
+            )->willReturnCallback(function (BeforeShareCreatedEvent $e): void {
2884
+                $e->setError('I won\'t let you share!');
2885
+                $e->stopPropagation();
2886
+            }
2887
+            );
2888
+
2889
+        $manager->createShare($share);
2890
+    }
2891
+
2892
+    public function testCreateShareOfIncomingFederatedShare(): void {
2893
+        $manager = $this->createManagerMock()
2894
+            ->onlyMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks'])
2895
+            ->getMock();
2896
+
2897
+        $shareOwner = $this->createMock(IUser::class);
2898
+        $shareOwner->method('getUID')->willReturn('shareOwner');
2899
+
2900
+        $storage = $this->createMock(IStorage::class);
2901
+        $storage->method('instanceOfStorage')
2902
+            ->with('OCA\Files_Sharing\External\Storage')
2903
+            ->willReturn(true);
2904
+
2905
+        $storage2 = $this->createMock(IStorage::class);
2906
+        $storage2->method('instanceOfStorage')
2907
+            ->with('OCA\Files_Sharing\External\Storage')
2908
+            ->willReturn(false);
2909
+
2910
+        $path = $this->createMock(File::class);
2911
+        $path->expects($this->never())->method('getOwner');
2912
+        $path->method('getName')->willReturn('target');
2913
+        $path->method('getStorage')->willReturn($storage);
2914
+
2915
+        $parent = $this->createMock(Folder::class);
2916
+        $parent->method('getStorage')->willReturn($storage);
2917
+
2918
+        $parentParent = $this->createMock(Folder::class);
2919
+        $parentParent->method('getStorage')->willReturn($storage2);
2920
+        $parentParent->method('getOwner')->willReturn($shareOwner);
2921
+
2922
+        $path->method('getParent')->willReturn($parent);
2923
+        $parent->method('getParent')->willReturn($parentParent);
2924
+
2925
+        $share = $this->createShare(
2926
+            null,
2927
+            IShare::TYPE_USER,
2928
+            $path,
2929
+            'sharedWith',
2930
+            'sharedBy',
2931
+            null,
2932
+            Constants::PERMISSION_ALL);
2933
+
2934
+        $manager->expects($this->once())
2935
+            ->method('canShare')
2936
+            ->with($share)
2937
+            ->willReturn(true);
2938
+        $manager->expects($this->once())
2939
+            ->method('generalCreateChecks')
2940
+            ->with($share);
2941
+        ;
2942
+        $manager->expects($this->once())
2943
+            ->method('userCreateChecks')
2944
+            ->with($share);
2945
+        ;
2946
+        $manager->expects($this->once())
2947
+            ->method('pathCreateChecks')
2948
+            ->with($path);
2949
+
2950
+        $this->defaultProvider
2951
+            ->expects($this->once())
2952
+            ->method('create')
2953
+            ->with($share)
2954
+            ->willReturnArgument(0);
2955
+
2956
+        $share->expects($this->once())
2957
+            ->method('setShareOwner')
2958
+            ->with('shareOwner');
2959
+        $share->expects($this->once())
2960
+            ->method('setTarget')
2961
+            ->with('/target');
2962
+
2963
+        $manager->createShare($share);
2964
+    }
2965
+
2966
+    public function testGetSharesBy(): void {
2967
+        $share = $this->manager->newShare();
2968
+
2969
+        $node = $this->createMock(Folder::class);
2970
+
2971
+        $this->defaultProvider->expects($this->once())
2972
+            ->method('getSharesBy')
2973
+            ->with(
2974
+                $this->equalTo('user'),
2975
+                $this->equalTo(IShare::TYPE_USER),
2976
+                $this->equalTo($node),
2977
+                $this->equalTo(true),
2978
+                $this->equalTo(1),
2979
+                $this->equalTo(1)
2980
+            )->willReturn([$share]);
2981
+
2982
+        $shares = $this->manager->getSharesBy('user', IShare::TYPE_USER, $node, true, 1, 1);
2983
+
2984
+        $this->assertCount(1, $shares);
2985
+        $this->assertSame($share, $shares[0]);
2986
+    }
2987
+
2988
+    public function testGetSharesByOwnerless(): void {
2989
+        $mount = $this->createMock(IShareOwnerlessMount::class);
2990
+
2991
+        $node = $this->createMock(Folder::class);
2992
+        $node
2993
+            ->expects($this->once())
2994
+            ->method('getMountPoint')
2995
+            ->willReturn($mount);
2996
+
2997
+        $share = $this->manager->newShare();
2998
+        $share->setNode($node);
2999
+        $share->setShareType(IShare::TYPE_USER);
3000
+
3001
+        $this->defaultProvider
3002
+            ->expects($this->once())
3003
+            ->method('getSharesByPath')
3004
+            ->with($this->equalTo($node))
3005
+            ->willReturn([$share]);
3006
+
3007
+        $shares = $this->manager->getSharesBy('user', IShare::TYPE_USER, $node, true, 1, 1);
3008
+
3009
+        $this->assertCount(1, $shares);
3010
+        $this->assertSame($share, $shares[0]);
3011
+    }
3012
+
3013
+    /**
3014
+     * Test to ensure we correctly remove expired link shares
3015
+     *
3016
+     * We have 8 Shares and we want the 3 first valid shares.
3017
+     * share 3-6 and 8 are expired. Thus at the end of this test we should
3018
+     * have received share 1,2 and 7. And from the manager. Share 3-6 should be
3019
+     * deleted (as they are evaluated). but share 8 should still be there.
3020
+     */
3021
+    public function testGetSharesByExpiredLinkShares(): void {
3022
+        $manager = $this->createManagerMock()
3023
+            ->onlyMethods(['deleteShare'])
3024
+            ->getMock();
3025
+
3026
+        /** @var IShare[] $shares */
3027
+        $shares = [];
3028
+
3029
+        /*
3030 3030
 		 * This results in an array of 8 IShare elements
3031 3031
 		 */
3032
-		for ($i = 0; $i < 8; $i++) {
3033
-			$share = $this->manager->newShare();
3034
-			$share->setId($i);
3035
-			$shares[] = $share;
3036
-		}
3032
+        for ($i = 0; $i < 8; $i++) {
3033
+            $share = $this->manager->newShare();
3034
+            $share->setId($i);
3035
+            $shares[] = $share;
3036
+        }
3037 3037
 
3038
-		$today = new \DateTime();
3039
-		$today->setTime(0, 0, 0);
3038
+        $today = new \DateTime();
3039
+        $today->setTime(0, 0, 0);
3040 3040
 
3041
-		/*
3041
+        /*
3042 3042
 		 * Set the expiration date to today for some shares
3043 3043
 		 */
3044
-		$shares[2]->setExpirationDate($today);
3045
-		$shares[3]->setExpirationDate($today);
3046
-		$shares[4]->setExpirationDate($today);
3047
-		$shares[5]->setExpirationDate($today);
3044
+        $shares[2]->setExpirationDate($today);
3045
+        $shares[3]->setExpirationDate($today);
3046
+        $shares[4]->setExpirationDate($today);
3047
+        $shares[5]->setExpirationDate($today);
3048 3048
 
3049
-		/** @var IShare[] $i */
3050
-		$shares2 = [];
3051
-		for ($i = 0; $i < 8; $i++) {
3052
-			$shares2[] = clone $shares[$i];
3053
-		}
3049
+        /** @var IShare[] $i */
3050
+        $shares2 = [];
3051
+        for ($i = 0; $i < 8; $i++) {
3052
+            $shares2[] = clone $shares[$i];
3053
+        }
3054 3054
 
3055
-		$node = $this->createMock(File::class);
3055
+        $node = $this->createMock(File::class);
3056 3056
 
3057
-		/*
3057
+        /*
3058 3058
 		 * Simulate the getSharesBy call.
3059 3059
 		 */
3060
-		$this->defaultProvider
3061
-			->method('getSharesBy')
3062
-			->willReturnCallback(function ($uid, $type, $node, $reshares, $limit, $offset) use (&$shares2) {
3063
-				return array_slice($shares2, $offset, $limit);
3064
-			});
3060
+        $this->defaultProvider
3061
+            ->method('getSharesBy')
3062
+            ->willReturnCallback(function ($uid, $type, $node, $reshares, $limit, $offset) use (&$shares2) {
3063
+                return array_slice($shares2, $offset, $limit);
3064
+            });
3065 3065
 
3066
-		/*
3066
+        /*
3067 3067
 		 * Simulate the deleteShare call.
3068 3068
 		 */
3069
-		$manager->method('deleteShare')
3070
-			->willReturnCallback(function ($share) use (&$shares2): void {
3071
-				for ($i = 0; $i < count($shares2); $i++) {
3072
-					if ($shares2[$i]->getId() === $share->getId()) {
3073
-						array_splice($shares2, $i, 1);
3074
-						break;
3075
-					}
3076
-				}
3077
-			});
3078
-
3079
-		$res = $manager->getSharesBy('user', IShare::TYPE_LINK, $node, true, 3, 0);
3080
-
3081
-		$this->assertCount(3, $res);
3082
-		$this->assertEquals($shares[0]->getId(), $res[0]->getId());
3083
-		$this->assertEquals($shares[1]->getId(), $res[1]->getId());
3084
-		$this->assertEquals($shares[6]->getId(), $res[2]->getId());
3085
-
3086
-		$this->assertCount(4, $shares2);
3087
-		$this->assertEquals(0, $shares2[0]->getId());
3088
-		$this->assertEquals(1, $shares2[1]->getId());
3089
-		$this->assertEquals(6, $shares2[2]->getId());
3090
-		$this->assertEquals(7, $shares2[3]->getId());
3091
-		$this->assertSame($today, $shares[3]->getExpirationDate());
3092
-	}
3093
-
3094
-	public function testGetShareByToken(): void {
3095
-		$this->config
3096
-			->expects($this->exactly(2))
3097
-			->method('getAppValue')
3098
-			->willReturnMap([
3099
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
3100
-				['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3101
-			]);
3102
-
3103
-		$factory = $this->createMock(IProviderFactory::class);
3104
-
3105
-		$manager = $this->createManager($factory);
3106
-
3107
-		$share = $this->createMock(IShare::class);
3108
-
3109
-		$factory->expects($this->once())
3110
-			->method('getProviderForType')
3111
-			->with(IShare::TYPE_LINK)
3112
-			->willReturn($this->defaultProvider);
3113
-
3114
-		$this->defaultProvider->expects($this->once())
3115
-			->method('getShareByToken')
3116
-			->with('token')
3117
-			->willReturn($share);
3118
-
3119
-		$ret = $manager->getShareByToken('token');
3120
-		$this->assertSame($share, $ret);
3121
-	}
3122
-
3123
-	public function testGetShareByTokenRoom(): void {
3124
-		$this->config
3125
-			->expects($this->exactly(2))
3126
-			->method('getAppValue')
3127
-			->willReturnMap([
3128
-				['core', 'shareapi_allow_links', 'yes', 'no'],
3129
-				['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3130
-			]);
3131
-
3132
-		$factory = $this->createMock(IProviderFactory::class);
3133
-
3134
-		$manager = $this->createManager($factory);
3135
-
3136
-		$share = $this->createMock(IShare::class);
3137
-
3138
-		$roomShareProvider = $this->createMock(IShareProvider::class);
3139
-
3140
-		$factory->expects($this->any())
3141
-			->method('getProviderForType')
3142
-			->willReturnCallback(function ($shareType) use ($roomShareProvider) {
3143
-				if ($shareType !== IShare::TYPE_ROOM) {
3144
-					throw new ProviderException();
3145
-				}
3146
-
3147
-				return $roomShareProvider;
3148
-			});
3149
-
3150
-		$roomShareProvider->expects($this->once())
3151
-			->method('getShareByToken')
3152
-			->with('token')
3153
-			->willReturn($share);
3154
-
3155
-		$ret = $manager->getShareByToken('token');
3156
-		$this->assertSame($share, $ret);
3157
-	}
3158
-
3159
-	public function testGetShareByTokenWithException(): void {
3160
-		$this->config
3161
-			->expects($this->exactly(2))
3162
-			->method('getAppValue')
3163
-			->willReturnMap([
3164
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
3165
-				['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3166
-			]);
3167
-
3168
-		$factory = $this->createMock(IProviderFactory::class);
3169
-
3170
-		$manager = $this->createManager($factory);
3171
-
3172
-		$share = $this->createMock(IShare::class);
3173
-
3174
-		$calls = [
3175
-			[IShare::TYPE_LINK],
3176
-			[IShare::TYPE_REMOTE],
3177
-		];
3178
-		$factory->expects($this->exactly(2))
3179
-			->method('getProviderForType')
3180
-			->willReturnCallback(function () use (&$calls) {
3181
-				$expected = array_shift($calls);
3182
-				$this->assertEquals($expected, func_get_args());
3183
-				return $this->defaultProvider;
3184
-			});
3185
-
3186
-		$this->defaultProvider->expects($this->exactly(2))
3187
-			->method('getShareByToken')
3188
-			->with('token')
3189
-			->willReturnOnConsecutiveCalls(
3190
-				$this->throwException(new ShareNotFound()),
3191
-				$share
3192
-			);
3193
-
3194
-		$ret = $manager->getShareByToken('token');
3195
-		$this->assertSame($share, $ret);
3196
-	}
3197
-
3198
-
3199
-	public function testGetShareByTokenHideDisabledUser(): void {
3200
-		$this->expectException(ShareNotFound::class);
3201
-		$this->expectExceptionMessage('The requested share comes from a disabled user');
3202
-
3203
-		$this->config
3204
-			->expects($this->exactly(2))
3205
-			->method('getAppValue')
3206
-			->willReturnMap([
3207
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
3208
-				['files_sharing', 'hide_disabled_user_shares', 'no', 'yes'],
3209
-			]);
3210
-
3211
-		$this->l->expects($this->once())
3212
-			->method('t')
3213
-			->willReturnArgument(0);
3214
-
3215
-		$manager = $this->createManagerMock()
3216
-			->onlyMethods(['deleteShare'])
3217
-			->getMock();
3218
-
3219
-		$date = new \DateTime();
3220
-		$date->setTime(0, 0, 0);
3221
-		$date->add(new \DateInterval('P2D'));
3222
-		$share = $this->manager->newShare();
3223
-		$share->setExpirationDate($date);
3224
-		$share->setShareOwner('owner');
3225
-		$share->setSharedBy('sharedBy');
3226
-
3227
-		$sharedBy = $this->createMock(IUser::class);
3228
-		$owner = $this->createMock(IUser::class);
3229
-
3230
-		$this->userManager->method('get')->willReturnMap([
3231
-			['sharedBy', $sharedBy],
3232
-			['owner', $owner],
3233
-		]);
3234
-
3235
-		$owner->expects($this->once())
3236
-			->method('isEnabled')
3237
-			->willReturn(true);
3238
-		$sharedBy->expects($this->once())
3239
-			->method('isEnabled')
3240
-			->willReturn(false);
3241
-
3242
-		$this->defaultProvider->expects($this->once())
3243
-			->method('getShareByToken')
3244
-			->with('expiredToken')
3245
-			->willReturn($share);
3246
-
3247
-		$manager->expects($this->never())
3248
-			->method('deleteShare');
3249
-
3250
-		$manager->getShareByToken('expiredToken');
3251
-	}
3252
-
3253
-
3254
-	public function testGetShareByTokenExpired(): void {
3255
-		$this->expectException(ShareNotFound::class);
3256
-		$this->expectExceptionMessage('The requested share does not exist anymore');
3257
-
3258
-		$this->config
3259
-			->expects($this->once())
3260
-			->method('getAppValue')
3261
-			->with('core', 'shareapi_allow_links', 'yes')
3262
-			->willReturn('yes');
3263
-
3264
-		$this->l->expects($this->once())
3265
-			->method('t')
3266
-			->willReturnArgument(0);
3267
-
3268
-		$manager = $this->createManagerMock()
3269
-			->onlyMethods(['deleteShare'])
3270
-			->getMock();
3271
-
3272
-		$date = new \DateTime();
3273
-		$date->setTime(0, 0, 0);
3274
-		$share = $this->manager->newShare();
3275
-		$share->setExpirationDate($date);
3276
-
3277
-		$this->defaultProvider->expects($this->once())
3278
-			->method('getShareByToken')
3279
-			->with('expiredToken')
3280
-			->willReturn($share);
3281
-
3282
-		$manager->expects($this->once())
3283
-			->method('deleteShare')
3284
-			->with($this->equalTo($share));
3285
-
3286
-		$manager->getShareByToken('expiredToken');
3287
-	}
3288
-
3289
-	public function testGetShareByTokenNotExpired(): void {
3290
-		$this->config
3291
-			->expects($this->exactly(2))
3292
-			->method('getAppValue')
3293
-			->willReturnMap([
3294
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
3295
-				['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3296
-			]);
3297
-
3298
-		$date = new \DateTime();
3299
-		$date->setTime(0, 0, 0);
3300
-		$date->add(new \DateInterval('P2D'));
3301
-		$share = $this->manager->newShare();
3302
-		$share->setExpirationDate($date);
3303
-
3304
-		$this->defaultProvider->expects($this->once())
3305
-			->method('getShareByToken')
3306
-			->with('expiredToken')
3307
-			->willReturn($share);
3308
-
3309
-		$res = $this->manager->getShareByToken('expiredToken');
3310
-
3311
-		$this->assertSame($share, $res);
3312
-	}
3313
-
3314
-
3315
-	public function testGetShareByTokenWithPublicLinksDisabled(): void {
3316
-		$this->expectException(ShareNotFound::class);
3317
-
3318
-		$this->config
3319
-			->expects($this->once())
3320
-			->method('getAppValue')
3321
-			->with('core', 'shareapi_allow_links', 'yes')
3322
-			->willReturn('no');
3323
-		$this->manager->getShareByToken('validToken');
3324
-	}
3325
-
3326
-	public function testGetShareByTokenPublicUploadDisabled(): void {
3327
-		$this->config
3328
-			->expects($this->exactly(3))
3329
-			->method('getAppValue')
3330
-			->willReturnMap([
3331
-				['core', 'shareapi_allow_links', 'yes', 'yes'],
3332
-				['core', 'shareapi_allow_public_upload', 'yes', 'no'],
3333
-				['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3334
-			]);
3335
-
3336
-		$share = $this->manager->newShare();
3337
-		$share->setShareType(IShare::TYPE_LINK)
3338
-			->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
3339
-		$share->setSharedWith('sharedWith');
3340
-		$folder = $this->createMock(\OC\Files\Node\Folder::class);
3341
-		$share->setNode($folder);
3342
-
3343
-		$this->defaultProvider->expects($this->once())
3344
-			->method('getShareByToken')
3345
-			->willReturn('validToken')
3346
-			->willReturn($share);
3347
-
3348
-		$res = $this->manager->getShareByToken('validToken');
3349
-
3350
-		$this->assertSame(Constants::PERMISSION_READ, $res->getPermissions());
3351
-	}
3352
-
3353
-	public function testCheckPasswordNoLinkShare(): void {
3354
-		$share = $this->createMock(IShare::class);
3355
-		$share->method('getShareType')->willReturn(IShare::TYPE_USER);
3356
-		$this->assertFalse($this->manager->checkPassword($share, 'password'));
3357
-	}
3358
-
3359
-	public function testCheckPasswordNoPassword(): void {
3360
-		$share = $this->createMock(IShare::class);
3361
-		$share->method('getShareType')->willReturn(IShare::TYPE_LINK);
3362
-		$this->assertFalse($this->manager->checkPassword($share, 'password'));
3363
-
3364
-		$share->method('getPassword')->willReturn('password');
3365
-		$this->assertFalse($this->manager->checkPassword($share, null));
3366
-	}
3367
-
3368
-	public function testCheckPasswordInvalidPassword(): void {
3369
-		$share = $this->createMock(IShare::class);
3370
-		$share->method('getShareType')->willReturn(IShare::TYPE_LINK);
3371
-		$share->method('getPassword')->willReturn('password');
3372
-
3373
-		$this->hasher->method('verify')->with('invalidpassword', 'password', '')->willReturn(false);
3374
-
3375
-		$this->assertFalse($this->manager->checkPassword($share, 'invalidpassword'));
3376
-	}
3377
-
3378
-	public function testCheckPasswordValidPassword(): void {
3379
-		$share = $this->createMock(IShare::class);
3380
-		$share->method('getShareType')->willReturn(IShare::TYPE_LINK);
3381
-		$share->method('getPassword')->willReturn('passwordHash');
3382
-
3383
-		$this->hasher->method('verify')->with('password', 'passwordHash', '')->willReturn(true);
3384
-
3385
-		$this->assertTrue($this->manager->checkPassword($share, 'password'));
3386
-	}
3387
-
3388
-	public function testCheckPasswordUpdateShare(): void {
3389
-		$share = $this->manager->newShare();
3390
-		$share->setShareType(IShare::TYPE_LINK)
3391
-			->setPassword('passwordHash');
3392
-
3393
-		$this->hasher->method('verify')->with('password', 'passwordHash', '')
3394
-			->willReturnCallback(function ($pass, $hash, &$newHash) {
3395
-				$newHash = 'newHash';
3396
-
3397
-				return true;
3398
-			});
3399
-
3400
-		$this->defaultProvider->expects($this->once())
3401
-			->method('update')
3402
-			->with($this->callback(function (IShare $share) {
3403
-				return $share->getPassword() === 'newHash';
3404
-			}));
3405
-
3406
-		$this->assertTrue($this->manager->checkPassword($share, 'password'));
3407
-	}
3408
-
3409
-
3410
-	public function testUpdateShareCantChangeShareType(): void {
3411
-		$this->expectException(\Exception::class);
3412
-		$this->expectExceptionMessage('Cannot change share type');
3413
-
3414
-		$manager = $this->createManagerMock()
3415
-			->onlyMethods([
3416
-				'canShare',
3417
-				'getShareById'
3418
-			])
3419
-			->getMock();
3420
-
3421
-		$originalShare = $this->manager->newShare();
3422
-		$originalShare->setShareType(IShare::TYPE_GROUP);
3423
-
3424
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3425
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3426
-
3427
-		$share = $this->manager->newShare();
3428
-		$attrs = $this->manager->newShare()->newAttributes();
3429
-		$attrs->setAttribute('app1', 'perm1', true);
3430
-		$share->setProviderId('foo')
3431
-			->setId('42')
3432
-			->setShareType(IShare::TYPE_USER);
3433
-
3434
-		$manager->updateShare($share);
3435
-	}
3436
-
3437
-
3438
-	public function testUpdateShareCantChangeRecipientForGroupShare(): void {
3439
-		$this->expectException(\Exception::class);
3440
-		$this->expectExceptionMessage('Can only update recipient on user shares');
3441
-
3442
-		$manager = $this->createManagerMock()
3443
-			->onlyMethods([
3444
-				'canShare',
3445
-				'getShareById'
3446
-			])
3447
-			->getMock();
3448
-
3449
-		$originalShare = $this->manager->newShare();
3450
-		$originalShare->setShareType(IShare::TYPE_GROUP)
3451
-			->setSharedWith('origGroup');
3452
-
3453
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3454
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3455
-
3456
-		$share = $this->manager->newShare();
3457
-		$share->setProviderId('foo')
3458
-			->setId('42')
3459
-			->setShareType(IShare::TYPE_GROUP)
3460
-			->setSharedWith('newGroup');
3461
-
3462
-		$manager->updateShare($share);
3463
-	}
3464
-
3465
-
3466
-	public function testUpdateShareCantShareWithOwner(): void {
3467
-		$this->expectException(\Exception::class);
3468
-		$this->expectExceptionMessage('Cannot share with the share owner');
3469
-
3470
-		$manager = $this->createManagerMock()
3471
-			->onlyMethods([
3472
-				'canShare',
3473
-				'getShareById'
3474
-			])
3475
-			->getMock();
3476
-
3477
-		$originalShare = $this->manager->newShare();
3478
-		$originalShare->setShareType(IShare::TYPE_USER)
3479
-			->setSharedWith('sharedWith');
3480
-
3481
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3482
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3483
-
3484
-		$share = $this->manager->newShare();
3485
-		$share->setProviderId('foo')
3486
-			->setId('42')
3487
-			->setShareType(IShare::TYPE_USER)
3488
-			->setSharedWith('newUser')
3489
-			->setShareOwner('newUser');
3490
-
3491
-		$manager->updateShare($share);
3492
-	}
3493
-
3494
-	public function testUpdateShareUser(): void {
3495
-		$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
3496
-
3497
-		$manager = $this->createManagerMock()
3498
-			->onlyMethods([
3499
-				'canShare',
3500
-				'getShareById',
3501
-				'generalCreateChecks',
3502
-				'userCreateChecks',
3503
-				'pathCreateChecks',
3504
-			])
3505
-			->getMock();
3506
-
3507
-		$originalShare = $this->manager->newShare();
3508
-		$originalShare->setShareType(IShare::TYPE_USER)
3509
-			->setSharedWith('origUser')
3510
-			->setPermissions(1);
3511
-
3512
-		$node = $this->createMock(File::class);
3513
-		$node->method('getId')->willReturn(100);
3514
-		$node->method('getPath')->willReturn('/newUser/files/myPath');
3515
-
3516
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3517
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3518
-
3519
-		$share = $this->manager->newShare();
3520
-		$attrs = $this->manager->newShare()->newAttributes();
3521
-		$attrs->setAttribute('app1', 'perm1', true);
3522
-		$share->setProviderId('foo')
3523
-			->setId('42')
3524
-			->setShareType(IShare::TYPE_USER)
3525
-			->setSharedWith('origUser')
3526
-			->setShareOwner('newUser')
3527
-			->setSharedBy('sharer')
3528
-			->setPermissions(31)
3529
-			->setAttributes($attrs)
3530
-			->setNode($node);
3531
-
3532
-		$this->defaultProvider->expects($this->once())
3533
-			->method('update')
3534
-			->with($share)
3535
-			->willReturn($share);
3536
-
3537
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3538
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3539
-		$hookListener->expects($this->never())->method('post');
3540
-
3541
-		$this->rootFolder->method('getUserFolder')->with('newUser')->willReturnSelf();
3542
-		$this->rootFolder->method('getRelativePath')->with('/newUser/files/myPath')->willReturn('/myPath');
3543
-
3544
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3545
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener2, 'post');
3546
-		$hookListener2->expects($this->once())->method('post')->with([
3547
-			'itemType' => 'file',
3548
-			'itemSource' => 100,
3549
-			'shareType' => IShare::TYPE_USER,
3550
-			'shareWith' => 'origUser',
3551
-			'uidOwner' => 'sharer',
3552
-			'permissions' => 31,
3553
-			'path' => '/myPath',
3554
-			'attributes' => $attrs->toArray(),
3555
-		]);
3556
-
3557
-		$manager->updateShare($share);
3558
-	}
3559
-
3560
-	public function testUpdateShareGroup(): void {
3561
-		$manager = $this->createManagerMock()
3562
-			->onlyMethods([
3563
-				'canShare',
3564
-				'getShareById',
3565
-				'generalCreateChecks',
3566
-				'groupCreateChecks',
3567
-				'pathCreateChecks',
3568
-			])
3569
-			->getMock();
3570
-
3571
-		$originalShare = $this->manager->newShare();
3572
-		$originalShare->setShareType(IShare::TYPE_GROUP)
3573
-			->setSharedWith('origUser')
3574
-			->setPermissions(31);
3575
-
3576
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3577
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3578
-
3579
-		$node = $this->createMock(File::class);
3580
-
3581
-		$share = $this->manager->newShare();
3582
-		$share->setProviderId('foo')
3583
-			->setId('42')
3584
-			->setShareType(IShare::TYPE_GROUP)
3585
-			->setSharedWith('origUser')
3586
-			->setShareOwner('owner')
3587
-			->setNode($node)
3588
-			->setPermissions(31);
3589
-
3590
-		$this->defaultProvider->expects($this->once())
3591
-			->method('update')
3592
-			->with($share)
3593
-			->willReturn($share);
3594
-
3595
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3596
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3597
-		$hookListener->expects($this->never())->method('post');
3598
-
3599
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3600
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener2, 'post');
3601
-		$hookListener2->expects($this->never())->method('post');
3602
-
3603
-		$manager->updateShare($share);
3604
-	}
3605
-
3606
-	public function testUpdateShareLink(): void {
3607
-		$manager = $this->createManagerMock()
3608
-			->onlyMethods([
3609
-				'canShare',
3610
-				'getShareById',
3611
-				'generalCreateChecks',
3612
-				'linkCreateChecks',
3613
-				'pathCreateChecks',
3614
-				'verifyPassword',
3615
-				'validateExpirationDateLink',
3616
-			])
3617
-			->getMock();
3618
-
3619
-		$originalShare = $this->manager->newShare();
3620
-		$originalShare->setShareType(IShare::TYPE_LINK)
3621
-			->setPermissions(15);
3622
-
3623
-		$tomorrow = new \DateTime();
3624
-		$tomorrow->setTime(0, 0, 0);
3625
-		$tomorrow->add(new \DateInterval('P1D'));
3626
-
3627
-		$file = $this->createMock(File::class);
3628
-		$file->method('getId')->willReturn(100);
3629
-
3630
-		$share = $this->manager->newShare();
3631
-		$share->setProviderId('foo')
3632
-			->setId('42')
3633
-			->setShareType(IShare::TYPE_LINK)
3634
-			->setToken('token')
3635
-			->setSharedBy('owner')
3636
-			->setShareOwner('owner')
3637
-			->setPassword('password')
3638
-			->setExpirationDate($tomorrow)
3639
-			->setNode($file)
3640
-			->setPermissions(15);
3641
-
3642
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3643
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3644
-		$manager->expects($this->once())->method('validateExpirationDateLink')->with($share);
3645
-		$manager->expects($this->once())->method('verifyPassword')->with('password');
3646
-
3647
-		$this->hasher->expects($this->once())
3648
-			->method('hash')
3649
-			->with('password')
3650
-			->willReturn('hashed');
3651
-
3652
-		$this->defaultProvider->expects($this->once())
3653
-			->method('update')
3654
-			->with($share)
3655
-			->willReturn($share);
3656
-
3657
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3658
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3659
-		$hookListener->expects($this->once())->method('post')->with([
3660
-			'itemType' => 'file',
3661
-			'itemSource' => 100,
3662
-			'date' => $tomorrow,
3663
-			'uidOwner' => 'owner',
3664
-		]);
3665
-
3666
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3667
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3668
-		$hookListener2->expects($this->once())->method('post')->with([
3669
-			'itemType' => 'file',
3670
-			'itemSource' => 100,
3671
-			'uidOwner' => 'owner',
3672
-			'token' => 'token',
3673
-			'disabled' => false,
3674
-		]);
3675
-
3676
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
3677
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3678
-		$hookListener3->expects($this->never())->method('post');
3679
-
3680
-
3681
-		$manager->updateShare($share);
3682
-	}
3683
-
3684
-	public function testUpdateShareLinkEnableSendPasswordByTalkWithNoPassword(): void {
3685
-		$this->expectException(\InvalidArgumentException::class);
3686
-		$this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
3687
-
3688
-		$manager = $this->createManagerMock()
3689
-			->onlyMethods([
3690
-				'canShare',
3691
-				'getShareById',
3692
-				'generalCreateChecks',
3693
-				'linkCreateChecks',
3694
-				'pathCreateChecks',
3695
-				'verifyPassword',
3696
-				'validateExpirationDateLink',
3697
-			])
3698
-			->getMock();
3699
-
3700
-		$originalShare = $this->manager->newShare();
3701
-		$originalShare->setShareType(IShare::TYPE_LINK)
3702
-			->setPermissions(15);
3703
-
3704
-		$tomorrow = new \DateTime();
3705
-		$tomorrow->setTime(0, 0, 0);
3706
-		$tomorrow->add(new \DateInterval('P1D'));
3707
-
3708
-		$file = $this->createMock(File::class);
3709
-		$file->method('getId')->willReturn(100);
3710
-
3711
-		$share = $this->manager->newShare();
3712
-		$share->setProviderId('foo')
3713
-			->setId('42')
3714
-			->setShareType(IShare::TYPE_LINK)
3715
-			->setToken('token')
3716
-			->setSharedBy('owner')
3717
-			->setShareOwner('owner')
3718
-			->setPassword(null)
3719
-			->setSendPasswordByTalk(true)
3720
-			->setExpirationDate($tomorrow)
3721
-			->setNode($file)
3722
-			->setPermissions(15);
3723
-
3724
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3725
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3726
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
3727
-		$manager->expects($this->once())->method('linkCreateChecks')->with($share);
3728
-		$manager->expects($this->never())->method('verifyPassword');
3729
-		$manager->expects($this->never())->method('pathCreateChecks');
3730
-		$manager->expects($this->never())->method('validateExpirationDateLink');
3731
-
3732
-		$this->hasher->expects($this->never())
3733
-			->method('hash');
3734
-
3735
-		$this->defaultProvider->expects($this->never())
3736
-			->method('update');
3737
-
3738
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3739
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3740
-		$hookListener->expects($this->never())->method('post');
3741
-
3742
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3743
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3744
-		$hookListener2->expects($this->never())->method('post');
3745
-
3746
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
3747
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3748
-		$hookListener3->expects($this->never())->method('post');
3749
-
3750
-		$manager->updateShare($share);
3751
-	}
3752
-
3753
-	public function testUpdateShareMail(): void {
3754
-		$manager = $this->createManagerMock()
3755
-			->onlyMethods([
3756
-				'canShare',
3757
-				'getShareById',
3758
-				'generalCreateChecks',
3759
-				'verifyPassword',
3760
-				'pathCreateChecks',
3761
-				'linkCreateChecks',
3762
-				'validateExpirationDateLink',
3763
-			])
3764
-			->getMock();
3765
-
3766
-		$originalShare = $this->manager->newShare();
3767
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
3768
-			->setPermissions(Constants::PERMISSION_ALL);
3769
-
3770
-		$tomorrow = new \DateTime();
3771
-		$tomorrow->setTime(0, 0, 0);
3772
-		$tomorrow->add(new \DateInterval('P1D'));
3773
-
3774
-		$file = $this->createMock(File::class);
3775
-		$file->method('getId')->willReturn(100);
3776
-
3777
-		$share = $this->manager->newShare();
3778
-		$share->setProviderId('foo')
3779
-			->setId('42')
3780
-			->setShareType(IShare::TYPE_EMAIL)
3781
-			->setToken('token')
3782
-			->setSharedBy('owner')
3783
-			->setShareOwner('owner')
3784
-			->setPassword('password')
3785
-			->setExpirationDate($tomorrow)
3786
-			->setNode($file)
3787
-			->setPermissions(Constants::PERMISSION_ALL);
3788
-
3789
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3790
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3791
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
3792
-		$manager->expects($this->once())->method('verifyPassword')->with('password');
3793
-		$manager->expects($this->once())->method('pathCreateChecks')->with($file);
3794
-		$manager->expects($this->once())->method('linkCreateChecks');
3795
-		$manager->expects($this->once())->method('validateExpirationDateLink');
3796
-
3797
-		$this->hasher->expects($this->once())
3798
-			->method('hash')
3799
-			->with('password')
3800
-			->willReturn('hashed');
3801
-
3802
-		$this->defaultProvider->expects($this->once())
3803
-			->method('update')
3804
-			->with($share, 'password')
3805
-			->willReturn($share);
3806
-
3807
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3808
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3809
-		$hookListener->expects($this->once())->method('post')->with([
3810
-			'itemType' => 'file',
3811
-			'itemSource' => 100,
3812
-			'date' => $tomorrow,
3813
-			'uidOwner' => 'owner',
3814
-		]);
3815
-
3816
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3817
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3818
-		$hookListener2->expects($this->once())->method('post')->with([
3819
-			'itemType' => 'file',
3820
-			'itemSource' => 100,
3821
-			'uidOwner' => 'owner',
3822
-			'token' => 'token',
3823
-			'disabled' => false,
3824
-		]);
3825
-
3826
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
3827
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3828
-		$hookListener3->expects($this->never())->method('post');
3829
-
3830
-		$manager->updateShare($share);
3831
-	}
3832
-
3833
-	public function testUpdateShareMailEnableSendPasswordByTalk(): void {
3834
-		$manager = $this->createManagerMock()
3835
-			->onlyMethods([
3836
-				'canShare',
3837
-				'getShareById',
3838
-				'generalCreateChecks',
3839
-				'verifyPassword',
3840
-				'pathCreateChecks',
3841
-				'linkCreateChecks',
3842
-				'validateExpirationDateLink',
3843
-			])
3844
-			->getMock();
3845
-
3846
-		$originalShare = $this->manager->newShare();
3847
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
3848
-			->setPermissions(Constants::PERMISSION_ALL)
3849
-			->setPassword(null)
3850
-			->setSendPasswordByTalk(false);
3851
-
3852
-		$tomorrow = new \DateTime();
3853
-		$tomorrow->setTime(0, 0, 0);
3854
-		$tomorrow->add(new \DateInterval('P1D'));
3855
-
3856
-		$file = $this->createMock(File::class);
3857
-		$file->method('getId')->willReturn(100);
3858
-
3859
-		$share = $this->manager->newShare();
3860
-		$share->setProviderId('foo')
3861
-			->setId('42')
3862
-			->setShareType(IShare::TYPE_EMAIL)
3863
-			->setToken('token')
3864
-			->setSharedBy('owner')
3865
-			->setShareOwner('owner')
3866
-			->setPassword('password')
3867
-			->setSendPasswordByTalk(true)
3868
-			->setExpirationDate($tomorrow)
3869
-			->setNode($file)
3870
-			->setPermissions(Constants::PERMISSION_ALL);
3871
-
3872
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3873
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3874
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
3875
-		$manager->expects($this->once())->method('verifyPassword')->with('password');
3876
-		$manager->expects($this->once())->method('pathCreateChecks')->with($file);
3877
-		$manager->expects($this->once())->method('linkCreateChecks');
3878
-		$manager->expects($this->once())->method('validateExpirationDateLink');
3879
-
3880
-		$this->hasher->expects($this->once())
3881
-			->method('hash')
3882
-			->with('password')
3883
-			->willReturn('hashed');
3884
-
3885
-		$this->defaultProvider->expects($this->once())
3886
-			->method('update')
3887
-			->with($share, 'password')
3888
-			->willReturn($share);
3889
-
3890
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3891
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3892
-		$hookListener->expects($this->once())->method('post')->with([
3893
-			'itemType' => 'file',
3894
-			'itemSource' => 100,
3895
-			'date' => $tomorrow,
3896
-			'uidOwner' => 'owner',
3897
-		]);
3898
-
3899
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3900
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3901
-		$hookListener2->expects($this->once())->method('post')->with([
3902
-			'itemType' => 'file',
3903
-			'itemSource' => 100,
3904
-			'uidOwner' => 'owner',
3905
-			'token' => 'token',
3906
-			'disabled' => false,
3907
-		]);
3908
-
3909
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
3910
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3911
-		$hookListener3->expects($this->never())->method('post');
3912
-
3913
-		$manager->updateShare($share);
3914
-	}
3915
-
3916
-	public function testUpdateShareMailEnableSendPasswordByTalkWithDifferentPassword(): void {
3917
-		$manager = $this->createManagerMock()
3918
-			->onlyMethods([
3919
-				'canShare',
3920
-				'getShareById',
3921
-				'generalCreateChecks',
3922
-				'verifyPassword',
3923
-				'pathCreateChecks',
3924
-				'linkCreateChecks',
3925
-				'validateExpirationDateLink',
3926
-			])
3927
-			->getMock();
3928
-
3929
-		$originalShare = $this->manager->newShare();
3930
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
3931
-			->setPermissions(Constants::PERMISSION_ALL)
3932
-			->setPassword('anotherPasswordHash')
3933
-			->setSendPasswordByTalk(false);
3934
-
3935
-		$tomorrow = new \DateTime();
3936
-		$tomorrow->setTime(0, 0, 0);
3937
-		$tomorrow->add(new \DateInterval('P1D'));
3938
-
3939
-		$file = $this->createMock(File::class);
3940
-		$file->method('getId')->willReturn(100);
3941
-
3942
-		$share = $this->manager->newShare();
3943
-		$share->setProviderId('foo')
3944
-			->setId('42')
3945
-			->setShareType(IShare::TYPE_EMAIL)
3946
-			->setToken('token')
3947
-			->setSharedBy('owner')
3948
-			->setShareOwner('owner')
3949
-			->setPassword('password')
3950
-			->setSendPasswordByTalk(true)
3951
-			->setExpirationDate($tomorrow)
3952
-			->setNode($file)
3953
-			->setPermissions(Constants::PERMISSION_ALL);
3954
-
3955
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
3956
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3957
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
3958
-		$manager->expects($this->once())->method('verifyPassword')->with('password');
3959
-		$manager->expects($this->once())->method('pathCreateChecks')->with($file);
3960
-		$manager->expects($this->once())->method('linkCreateChecks');
3961
-		$manager->expects($this->once())->method('validateExpirationDateLink');
3962
-
3963
-		$this->hasher->expects($this->once())
3964
-			->method('verify')
3965
-			->with('password', 'anotherPasswordHash')
3966
-			->willReturn(false);
3967
-
3968
-		$this->hasher->expects($this->once())
3969
-			->method('hash')
3970
-			->with('password')
3971
-			->willReturn('hashed');
3972
-
3973
-		$this->defaultProvider->expects($this->once())
3974
-			->method('update')
3975
-			->with($share, 'password')
3976
-			->willReturn($share);
3977
-
3978
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
3979
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3980
-		$hookListener->expects($this->once())->method('post')->with([
3981
-			'itemType' => 'file',
3982
-			'itemSource' => 100,
3983
-			'date' => $tomorrow,
3984
-			'uidOwner' => 'owner',
3985
-		]);
3986
-
3987
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
3988
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3989
-		$hookListener2->expects($this->once())->method('post')->with([
3990
-			'itemType' => 'file',
3991
-			'itemSource' => 100,
3992
-			'uidOwner' => 'owner',
3993
-			'token' => 'token',
3994
-			'disabled' => false,
3995
-		]);
3996
-
3997
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
3998
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3999
-		$hookListener3->expects($this->never())->method('post');
4000
-
4001
-		$manager->updateShare($share);
4002
-	}
4003
-
4004
-	public function testUpdateShareMailEnableSendPasswordByTalkWithNoPassword(): void {
4005
-		$this->expectException(\InvalidArgumentException::class);
4006
-		$this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
4007
-
4008
-		$manager = $this->createManagerMock()
4009
-			->onlyMethods([
4010
-				'canShare',
4011
-				'getShareById',
4012
-				'generalCreateChecks',
4013
-				'verifyPassword',
4014
-				'pathCreateChecks',
4015
-				'linkCreateChecks',
4016
-				'validateExpirationDateLink',
4017
-			])
4018
-			->getMock();
4019
-
4020
-		$originalShare = $this->manager->newShare();
4021
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
4022
-			->setPermissions(Constants::PERMISSION_ALL)
4023
-			->setPassword(null)
4024
-			->setSendPasswordByTalk(false);
4025
-
4026
-		$tomorrow = new \DateTime();
4027
-		$tomorrow->setTime(0, 0, 0);
4028
-		$tomorrow->add(new \DateInterval('P1D'));
4029
-
4030
-		$file = $this->createMock(File::class);
4031
-		$file->method('getId')->willReturn(100);
4032
-
4033
-		$share = $this->manager->newShare();
4034
-		$share->setProviderId('foo')
4035
-			->setId('42')
4036
-			->setShareType(IShare::TYPE_EMAIL)
4037
-			->setToken('token')
4038
-			->setSharedBy('owner')
4039
-			->setShareOwner('owner')
4040
-			->setPassword(null)
4041
-			->setSendPasswordByTalk(true)
4042
-			->setExpirationDate($tomorrow)
4043
-			->setNode($file)
4044
-			->setPermissions(Constants::PERMISSION_ALL);
4045
-
4046
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
4047
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4048
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
4049
-		$manager->expects($this->never())->method('verifyPassword');
4050
-		$manager->expects($this->never())->method('pathCreateChecks');
4051
-		$manager->expects($this->once())->method('linkCreateChecks');
4052
-		$manager->expects($this->never())->method('validateExpirationDateLink');
4053
-
4054
-		// If the password is empty, we have nothing to hash
4055
-		$this->hasher->expects($this->never())
4056
-			->method('hash');
4057
-
4058
-		$this->defaultProvider->expects($this->never())
4059
-			->method('update');
4060
-
4061
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
4062
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4063
-		$hookListener->expects($this->never())->method('post');
4064
-
4065
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
4066
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4067
-		$hookListener2->expects($this->never())->method('post');
4068
-
4069
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
4070
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4071
-		$hookListener3->expects($this->never())->method('post');
4072
-
4073
-		$manager->updateShare($share);
4074
-	}
4075
-
4076
-
4077
-	public function testUpdateShareMailEnableSendPasswordByTalkRemovingPassword(): void {
4078
-		$this->expectException(\InvalidArgumentException::class);
4079
-		$this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
4080
-
4081
-		$manager = $this->createManagerMock()
4082
-			->onlyMethods([
4083
-				'canShare',
4084
-				'getShareById',
4085
-				'generalCreateChecks',
4086
-				'verifyPassword',
4087
-				'pathCreateChecks',
4088
-				'linkCreateChecks',
4089
-				'validateExpirationDateLink',
4090
-			])
4091
-			->getMock();
4092
-
4093
-		$originalShare = $this->manager->newShare();
4094
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
4095
-			->setPermissions(Constants::PERMISSION_ALL)
4096
-			->setPassword('passwordHash')
4097
-			->setSendPasswordByTalk(false);
4098
-
4099
-		$tomorrow = new \DateTime();
4100
-		$tomorrow->setTime(0, 0, 0);
4101
-		$tomorrow->add(new \DateInterval('P1D'));
4102
-
4103
-		$file = $this->createMock(File::class);
4104
-		$file->method('getId')->willReturn(100);
4105
-
4106
-		$share = $this->manager->newShare();
4107
-		$share->setProviderId('foo')
4108
-			->setId('42')
4109
-			->setShareType(IShare::TYPE_EMAIL)
4110
-			->setToken('token')
4111
-			->setSharedBy('owner')
4112
-			->setShareOwner('owner')
4113
-			->setPassword(null)
4114
-			->setSendPasswordByTalk(true)
4115
-			->setExpirationDate($tomorrow)
4116
-			->setNode($file)
4117
-			->setPermissions(Constants::PERMISSION_ALL);
4118
-
4119
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
4120
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4121
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
4122
-		$manager->expects($this->once())->method('verifyPassword');
4123
-		$manager->expects($this->never())->method('pathCreateChecks');
4124
-		$manager->expects($this->once())->method('linkCreateChecks');
4125
-		$manager->expects($this->never())->method('validateExpirationDateLink');
4126
-
4127
-		// If the password is empty, we have nothing to hash
4128
-		$this->hasher->expects($this->never())
4129
-			->method('hash');
4130
-
4131
-		$this->defaultProvider->expects($this->never())
4132
-			->method('update');
4133
-
4134
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
4135
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4136
-		$hookListener->expects($this->never())->method('post');
4137
-
4138
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
4139
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4140
-		$hookListener2->expects($this->never())->method('post');
4141
-
4142
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
4143
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4144
-		$hookListener3->expects($this->never())->method('post');
4145
-
4146
-		$manager->updateShare($share);
4147
-	}
4148
-
4149
-
4150
-	public function testUpdateShareMailEnableSendPasswordByTalkRemovingPasswordWithEmptyString(): void {
4151
-		$this->expectException(\InvalidArgumentException::class);
4152
-		$this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
4153
-
4154
-		$manager = $this->createManagerMock()
4155
-			->onlyMethods([
4156
-				'canShare',
4157
-				'getShareById',
4158
-				'generalCreateChecks',
4159
-				'verifyPassword',
4160
-				'pathCreateChecks',
4161
-				'linkCreateChecks',
4162
-				'validateExpirationDateLink',
4163
-			])
4164
-			->getMock();
4165
-
4166
-		$originalShare = $this->manager->newShare();
4167
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
4168
-			->setPermissions(Constants::PERMISSION_ALL)
4169
-			->setPassword('passwordHash')
4170
-			->setSendPasswordByTalk(false);
4171
-
4172
-		$tomorrow = new \DateTime();
4173
-		$tomorrow->setTime(0, 0, 0);
4174
-		$tomorrow->add(new \DateInterval('P1D'));
4175
-
4176
-		$file = $this->createMock(File::class);
4177
-		$file->method('getId')->willReturn(100);
4178
-
4179
-		$share = $this->manager->newShare();
4180
-		$share->setProviderId('foo')
4181
-			->setId('42')
4182
-			->setShareType(IShare::TYPE_EMAIL)
4183
-			->setToken('token')
4184
-			->setSharedBy('owner')
4185
-			->setShareOwner('owner')
4186
-			->setPassword('')
4187
-			->setSendPasswordByTalk(true)
4188
-			->setExpirationDate($tomorrow)
4189
-			->setNode($file)
4190
-			->setPermissions(Constants::PERMISSION_ALL);
4191
-
4192
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
4193
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4194
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
4195
-		$manager->expects($this->once())->method('verifyPassword');
4196
-		$manager->expects($this->never())->method('pathCreateChecks');
4197
-		$manager->expects($this->once())->method('linkCreateChecks');
4198
-		$manager->expects($this->never())->method('validateExpirationDateLink');
4199
-
4200
-		// If the password is empty, we have nothing to hash
4201
-		$this->hasher->expects($this->never())
4202
-			->method('hash');
4203
-
4204
-		$this->defaultProvider->expects($this->never())
4205
-			->method('update');
4206
-
4207
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
4208
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4209
-		$hookListener->expects($this->never())->method('post');
4210
-
4211
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
4212
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4213
-		$hookListener2->expects($this->never())->method('post');
4214
-
4215
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
4216
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4217
-		$hookListener3->expects($this->never())->method('post');
4218
-
4219
-		$manager->updateShare($share);
4220
-	}
4221
-
4222
-
4223
-	public function testUpdateShareMailEnableSendPasswordByTalkWithPreviousPassword(): void {
4224
-		$this->expectException(\InvalidArgumentException::class);
4225
-		$this->expectExceptionMessage('Cannot enable sending the password by Talk without setting a new password');
4226
-
4227
-		$manager = $this->createManagerMock()
4228
-			->onlyMethods([
4229
-				'canShare',
4230
-				'getShareById',
4231
-				'generalCreateChecks',
4232
-				'verifyPassword',
4233
-				'pathCreateChecks',
4234
-				'linkCreateChecks',
4235
-				'validateExpirationDateLink',
4236
-			])
4237
-			->getMock();
4238
-
4239
-		$originalShare = $this->manager->newShare();
4240
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
4241
-			->setPermissions(Constants::PERMISSION_ALL)
4242
-			->setPassword('password')
4243
-			->setSendPasswordByTalk(false);
4244
-
4245
-		$tomorrow = new \DateTime();
4246
-		$tomorrow->setTime(0, 0, 0);
4247
-		$tomorrow->add(new \DateInterval('P1D'));
4248
-
4249
-		$file = $this->createMock(File::class);
4250
-		$file->method('getId')->willReturn(100);
4251
-
4252
-		$share = $this->manager->newShare();
4253
-		$share->setProviderId('foo')
4254
-			->setId('42')
4255
-			->setShareType(IShare::TYPE_EMAIL)
4256
-			->setToken('token')
4257
-			->setSharedBy('owner')
4258
-			->setShareOwner('owner')
4259
-			->setPassword('password')
4260
-			->setSendPasswordByTalk(true)
4261
-			->setExpirationDate($tomorrow)
4262
-			->setNode($file)
4263
-			->setPermissions(Constants::PERMISSION_ALL);
4264
-
4265
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
4266
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4267
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
4268
-		$manager->expects($this->never())->method('verifyPassword');
4269
-		$manager->expects($this->never())->method('pathCreateChecks');
4270
-		$manager->expects($this->once())->method('linkCreateChecks');
4271
-		$manager->expects($this->never())->method('validateExpirationDateLink');
4272
-
4273
-		// If the old & new passwords are the same, we don't do anything
4274
-		$this->hasher->expects($this->never())
4275
-			->method('verify');
4276
-		$this->hasher->expects($this->never())
4277
-			->method('hash');
4278
-
4279
-		$this->defaultProvider->expects($this->never())
4280
-			->method('update');
4281
-
4282
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
4283
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4284
-		$hookListener->expects($this->never())->method('post');
4285
-
4286
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
4287
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4288
-		$hookListener2->expects($this->never())->method('post');
4289
-
4290
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
4291
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4292
-		$hookListener3->expects($this->never())->method('post');
4293
-
4294
-		$manager->updateShare($share);
4295
-	}
4296
-
4297
-	public function testUpdateShareMailDisableSendPasswordByTalkWithPreviousPassword(): void {
4298
-		$this->expectException(\InvalidArgumentException::class);
4299
-		$this->expectExceptionMessage('Cannot disable sending the password by Talk without setting a new password');
4300
-
4301
-		$manager = $this->createManagerMock()
4302
-			->onlyMethods([
4303
-				'canShare',
4304
-				'getShareById',
4305
-				'generalCreateChecks',
4306
-				'verifyPassword',
4307
-				'pathCreateChecks',
4308
-				'linkCreateChecks',
4309
-				'validateExpirationDateLink',
4310
-			])
4311
-			->getMock();
4312
-
4313
-		$originalShare = $this->manager->newShare();
4314
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
4315
-			->setPermissions(Constants::PERMISSION_ALL)
4316
-			->setPassword('passwordHash')
4317
-			->setSendPasswordByTalk(true);
4318
-
4319
-		$tomorrow = new \DateTime();
4320
-		$tomorrow->setTime(0, 0, 0);
4321
-		$tomorrow->add(new \DateInterval('P1D'));
4322
-
4323
-		$file = $this->createMock(File::class);
4324
-		$file->method('getId')->willReturn(100);
4325
-
4326
-		$share = $this->manager->newShare();
4327
-		$share->setProviderId('foo')
4328
-			->setId('42')
4329
-			->setShareType(IShare::TYPE_EMAIL)
4330
-			->setToken('token')
4331
-			->setSharedBy('owner')
4332
-			->setShareOwner('owner')
4333
-			->setPassword('passwordHash')
4334
-			->setSendPasswordByTalk(false)
4335
-			->setExpirationDate($tomorrow)
4336
-			->setNode($file)
4337
-			->setPermissions(Constants::PERMISSION_ALL);
4338
-
4339
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
4340
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4341
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
4342
-		$manager->expects($this->never())->method('verifyPassword');
4343
-		$manager->expects($this->never())->method('pathCreateChecks');
4344
-		$manager->expects($this->once())->method('linkCreateChecks');
4345
-		$manager->expects($this->never())->method('validateExpirationDateLink');
4346
-
4347
-		// If the old & new passwords are the same, we don't do anything
4348
-		$this->hasher->expects($this->never())
4349
-			->method('verify');
4350
-		$this->hasher->expects($this->never())
4351
-			->method('hash');
4352
-
4353
-		$this->defaultProvider->expects($this->never())
4354
-			->method('update');
4355
-
4356
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
4357
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4358
-		$hookListener->expects($this->never())->method('post');
4359
-
4360
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
4361
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4362
-		$hookListener2->expects($this->never())->method('post');
4363
-
4364
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
4365
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4366
-		$hookListener3->expects($this->never())->method('post');
4367
-
4368
-		$manager->updateShare($share);
4369
-	}
4370
-
4371
-	public function testUpdateShareMailDisableSendPasswordByTalkWithoutChangingPassword(): void {
4372
-		$this->expectException(\InvalidArgumentException::class);
4373
-		$this->expectExceptionMessage('Cannot disable sending the password by Talk without setting a new password');
4374
-
4375
-		$manager = $this->createManagerMock()
4376
-			->onlyMethods([
4377
-				'canShare',
4378
-				'getShareById',
4379
-				'generalCreateChecks',
4380
-				'verifyPassword',
4381
-				'pathCreateChecks',
4382
-				'linkCreateChecks',
4383
-				'validateExpirationDateLink',
4384
-			])
4385
-			->getMock();
4386
-
4387
-		$originalShare = $this->manager->newShare();
4388
-		$originalShare->setShareType(IShare::TYPE_EMAIL)
4389
-			->setPermissions(Constants::PERMISSION_ALL)
4390
-			->setPassword('passwordHash')
4391
-			->setSendPasswordByTalk(true);
4392
-
4393
-		$tomorrow = new \DateTime();
4394
-		$tomorrow->setTime(0, 0, 0);
4395
-		$tomorrow->add(new \DateInterval('P1D'));
4396
-
4397
-		$file = $this->createMock(File::class);
4398
-		$file->method('getId')->willReturn(100);
4399
-
4400
-		$share = $this->manager->newShare();
4401
-		$share->setProviderId('foo')
4402
-			->setId('42')
4403
-			->setShareType(IShare::TYPE_EMAIL)
4404
-			->setToken('token')
4405
-			->setSharedBy('owner')
4406
-			->setShareOwner('owner')
4407
-			->setPassword('passwordHash')
4408
-			->setSendPasswordByTalk(false)
4409
-			->setExpirationDate($tomorrow)
4410
-			->setNode($file)
4411
-			->setPermissions(Constants::PERMISSION_ALL);
4412
-
4413
-		$manager->expects($this->once())->method('canShare')->willReturn(true);
4414
-		$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4415
-		$manager->expects($this->once())->method('generalCreateChecks')->with($share);
4416
-		$manager->expects($this->never())->method('verifyPassword');
4417
-		$manager->expects($this->never())->method('pathCreateChecks');
4418
-		$manager->expects($this->once())->method('linkCreateChecks');
4419
-		$manager->expects($this->never())->method('validateExpirationDateLink');
4420
-
4421
-		// If the old & new passwords are the same, we don't do anything
4422
-		$this->hasher->expects($this->never())
4423
-			->method('verify');
4424
-		$this->hasher->expects($this->never())
4425
-			->method('hash');
4426
-
4427
-		$this->defaultProvider->expects($this->never())
4428
-			->method('update');
4429
-
4430
-		$hookListener = $this->createMock(DummyShareManagerListener::class);
4431
-		Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4432
-		$hookListener->expects($this->never())->method('post');
3069
+        $manager->method('deleteShare')
3070
+            ->willReturnCallback(function ($share) use (&$shares2): void {
3071
+                for ($i = 0; $i < count($shares2); $i++) {
3072
+                    if ($shares2[$i]->getId() === $share->getId()) {
3073
+                        array_splice($shares2, $i, 1);
3074
+                        break;
3075
+                    }
3076
+                }
3077
+            });
3078
+
3079
+        $res = $manager->getSharesBy('user', IShare::TYPE_LINK, $node, true, 3, 0);
3080
+
3081
+        $this->assertCount(3, $res);
3082
+        $this->assertEquals($shares[0]->getId(), $res[0]->getId());
3083
+        $this->assertEquals($shares[1]->getId(), $res[1]->getId());
3084
+        $this->assertEquals($shares[6]->getId(), $res[2]->getId());
3085
+
3086
+        $this->assertCount(4, $shares2);
3087
+        $this->assertEquals(0, $shares2[0]->getId());
3088
+        $this->assertEquals(1, $shares2[1]->getId());
3089
+        $this->assertEquals(6, $shares2[2]->getId());
3090
+        $this->assertEquals(7, $shares2[3]->getId());
3091
+        $this->assertSame($today, $shares[3]->getExpirationDate());
3092
+    }
3093
+
3094
+    public function testGetShareByToken(): void {
3095
+        $this->config
3096
+            ->expects($this->exactly(2))
3097
+            ->method('getAppValue')
3098
+            ->willReturnMap([
3099
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
3100
+                ['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3101
+            ]);
3102
+
3103
+        $factory = $this->createMock(IProviderFactory::class);
3104
+
3105
+        $manager = $this->createManager($factory);
3106
+
3107
+        $share = $this->createMock(IShare::class);
3108
+
3109
+        $factory->expects($this->once())
3110
+            ->method('getProviderForType')
3111
+            ->with(IShare::TYPE_LINK)
3112
+            ->willReturn($this->defaultProvider);
3113
+
3114
+        $this->defaultProvider->expects($this->once())
3115
+            ->method('getShareByToken')
3116
+            ->with('token')
3117
+            ->willReturn($share);
3118
+
3119
+        $ret = $manager->getShareByToken('token');
3120
+        $this->assertSame($share, $ret);
3121
+    }
3122
+
3123
+    public function testGetShareByTokenRoom(): void {
3124
+        $this->config
3125
+            ->expects($this->exactly(2))
3126
+            ->method('getAppValue')
3127
+            ->willReturnMap([
3128
+                ['core', 'shareapi_allow_links', 'yes', 'no'],
3129
+                ['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3130
+            ]);
3131
+
3132
+        $factory = $this->createMock(IProviderFactory::class);
3133
+
3134
+        $manager = $this->createManager($factory);
3135
+
3136
+        $share = $this->createMock(IShare::class);
3137
+
3138
+        $roomShareProvider = $this->createMock(IShareProvider::class);
3139
+
3140
+        $factory->expects($this->any())
3141
+            ->method('getProviderForType')
3142
+            ->willReturnCallback(function ($shareType) use ($roomShareProvider) {
3143
+                if ($shareType !== IShare::TYPE_ROOM) {
3144
+                    throw new ProviderException();
3145
+                }
3146
+
3147
+                return $roomShareProvider;
3148
+            });
3149
+
3150
+        $roomShareProvider->expects($this->once())
3151
+            ->method('getShareByToken')
3152
+            ->with('token')
3153
+            ->willReturn($share);
3154
+
3155
+        $ret = $manager->getShareByToken('token');
3156
+        $this->assertSame($share, $ret);
3157
+    }
3158
+
3159
+    public function testGetShareByTokenWithException(): void {
3160
+        $this->config
3161
+            ->expects($this->exactly(2))
3162
+            ->method('getAppValue')
3163
+            ->willReturnMap([
3164
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
3165
+                ['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3166
+            ]);
3167
+
3168
+        $factory = $this->createMock(IProviderFactory::class);
3169
+
3170
+        $manager = $this->createManager($factory);
3171
+
3172
+        $share = $this->createMock(IShare::class);
3173
+
3174
+        $calls = [
3175
+            [IShare::TYPE_LINK],
3176
+            [IShare::TYPE_REMOTE],
3177
+        ];
3178
+        $factory->expects($this->exactly(2))
3179
+            ->method('getProviderForType')
3180
+            ->willReturnCallback(function () use (&$calls) {
3181
+                $expected = array_shift($calls);
3182
+                $this->assertEquals($expected, func_get_args());
3183
+                return $this->defaultProvider;
3184
+            });
3185
+
3186
+        $this->defaultProvider->expects($this->exactly(2))
3187
+            ->method('getShareByToken')
3188
+            ->with('token')
3189
+            ->willReturnOnConsecutiveCalls(
3190
+                $this->throwException(new ShareNotFound()),
3191
+                $share
3192
+            );
3193
+
3194
+        $ret = $manager->getShareByToken('token');
3195
+        $this->assertSame($share, $ret);
3196
+    }
3197
+
3198
+
3199
+    public function testGetShareByTokenHideDisabledUser(): void {
3200
+        $this->expectException(ShareNotFound::class);
3201
+        $this->expectExceptionMessage('The requested share comes from a disabled user');
3202
+
3203
+        $this->config
3204
+            ->expects($this->exactly(2))
3205
+            ->method('getAppValue')
3206
+            ->willReturnMap([
3207
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
3208
+                ['files_sharing', 'hide_disabled_user_shares', 'no', 'yes'],
3209
+            ]);
3210
+
3211
+        $this->l->expects($this->once())
3212
+            ->method('t')
3213
+            ->willReturnArgument(0);
3214
+
3215
+        $manager = $this->createManagerMock()
3216
+            ->onlyMethods(['deleteShare'])
3217
+            ->getMock();
3218
+
3219
+        $date = new \DateTime();
3220
+        $date->setTime(0, 0, 0);
3221
+        $date->add(new \DateInterval('P2D'));
3222
+        $share = $this->manager->newShare();
3223
+        $share->setExpirationDate($date);
3224
+        $share->setShareOwner('owner');
3225
+        $share->setSharedBy('sharedBy');
3226
+
3227
+        $sharedBy = $this->createMock(IUser::class);
3228
+        $owner = $this->createMock(IUser::class);
3229
+
3230
+        $this->userManager->method('get')->willReturnMap([
3231
+            ['sharedBy', $sharedBy],
3232
+            ['owner', $owner],
3233
+        ]);
3234
+
3235
+        $owner->expects($this->once())
3236
+            ->method('isEnabled')
3237
+            ->willReturn(true);
3238
+        $sharedBy->expects($this->once())
3239
+            ->method('isEnabled')
3240
+            ->willReturn(false);
3241
+
3242
+        $this->defaultProvider->expects($this->once())
3243
+            ->method('getShareByToken')
3244
+            ->with('expiredToken')
3245
+            ->willReturn($share);
3246
+
3247
+        $manager->expects($this->never())
3248
+            ->method('deleteShare');
3249
+
3250
+        $manager->getShareByToken('expiredToken');
3251
+    }
3252
+
3253
+
3254
+    public function testGetShareByTokenExpired(): void {
3255
+        $this->expectException(ShareNotFound::class);
3256
+        $this->expectExceptionMessage('The requested share does not exist anymore');
3257
+
3258
+        $this->config
3259
+            ->expects($this->once())
3260
+            ->method('getAppValue')
3261
+            ->with('core', 'shareapi_allow_links', 'yes')
3262
+            ->willReturn('yes');
3263
+
3264
+        $this->l->expects($this->once())
3265
+            ->method('t')
3266
+            ->willReturnArgument(0);
3267
+
3268
+        $manager = $this->createManagerMock()
3269
+            ->onlyMethods(['deleteShare'])
3270
+            ->getMock();
3271
+
3272
+        $date = new \DateTime();
3273
+        $date->setTime(0, 0, 0);
3274
+        $share = $this->manager->newShare();
3275
+        $share->setExpirationDate($date);
3276
+
3277
+        $this->defaultProvider->expects($this->once())
3278
+            ->method('getShareByToken')
3279
+            ->with('expiredToken')
3280
+            ->willReturn($share);
3281
+
3282
+        $manager->expects($this->once())
3283
+            ->method('deleteShare')
3284
+            ->with($this->equalTo($share));
3285
+
3286
+        $manager->getShareByToken('expiredToken');
3287
+    }
3288
+
3289
+    public function testGetShareByTokenNotExpired(): void {
3290
+        $this->config
3291
+            ->expects($this->exactly(2))
3292
+            ->method('getAppValue')
3293
+            ->willReturnMap([
3294
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
3295
+                ['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3296
+            ]);
3297
+
3298
+        $date = new \DateTime();
3299
+        $date->setTime(0, 0, 0);
3300
+        $date->add(new \DateInterval('P2D'));
3301
+        $share = $this->manager->newShare();
3302
+        $share->setExpirationDate($date);
3303
+
3304
+        $this->defaultProvider->expects($this->once())
3305
+            ->method('getShareByToken')
3306
+            ->with('expiredToken')
3307
+            ->willReturn($share);
3308
+
3309
+        $res = $this->manager->getShareByToken('expiredToken');
3310
+
3311
+        $this->assertSame($share, $res);
3312
+    }
3313
+
3314
+
3315
+    public function testGetShareByTokenWithPublicLinksDisabled(): void {
3316
+        $this->expectException(ShareNotFound::class);
3317
+
3318
+        $this->config
3319
+            ->expects($this->once())
3320
+            ->method('getAppValue')
3321
+            ->with('core', 'shareapi_allow_links', 'yes')
3322
+            ->willReturn('no');
3323
+        $this->manager->getShareByToken('validToken');
3324
+    }
3325
+
3326
+    public function testGetShareByTokenPublicUploadDisabled(): void {
3327
+        $this->config
3328
+            ->expects($this->exactly(3))
3329
+            ->method('getAppValue')
3330
+            ->willReturnMap([
3331
+                ['core', 'shareapi_allow_links', 'yes', 'yes'],
3332
+                ['core', 'shareapi_allow_public_upload', 'yes', 'no'],
3333
+                ['files_sharing', 'hide_disabled_user_shares', 'no', 'no'],
3334
+            ]);
3335
+
3336
+        $share = $this->manager->newShare();
3337
+        $share->setShareType(IShare::TYPE_LINK)
3338
+            ->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE);
3339
+        $share->setSharedWith('sharedWith');
3340
+        $folder = $this->createMock(\OC\Files\Node\Folder::class);
3341
+        $share->setNode($folder);
3342
+
3343
+        $this->defaultProvider->expects($this->once())
3344
+            ->method('getShareByToken')
3345
+            ->willReturn('validToken')
3346
+            ->willReturn($share);
3347
+
3348
+        $res = $this->manager->getShareByToken('validToken');
3349
+
3350
+        $this->assertSame(Constants::PERMISSION_READ, $res->getPermissions());
3351
+    }
3352
+
3353
+    public function testCheckPasswordNoLinkShare(): void {
3354
+        $share = $this->createMock(IShare::class);
3355
+        $share->method('getShareType')->willReturn(IShare::TYPE_USER);
3356
+        $this->assertFalse($this->manager->checkPassword($share, 'password'));
3357
+    }
3358
+
3359
+    public function testCheckPasswordNoPassword(): void {
3360
+        $share = $this->createMock(IShare::class);
3361
+        $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
3362
+        $this->assertFalse($this->manager->checkPassword($share, 'password'));
3363
+
3364
+        $share->method('getPassword')->willReturn('password');
3365
+        $this->assertFalse($this->manager->checkPassword($share, null));
3366
+    }
3367
+
3368
+    public function testCheckPasswordInvalidPassword(): void {
3369
+        $share = $this->createMock(IShare::class);
3370
+        $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
3371
+        $share->method('getPassword')->willReturn('password');
3372
+
3373
+        $this->hasher->method('verify')->with('invalidpassword', 'password', '')->willReturn(false);
3374
+
3375
+        $this->assertFalse($this->manager->checkPassword($share, 'invalidpassword'));
3376
+    }
3377
+
3378
+    public function testCheckPasswordValidPassword(): void {
3379
+        $share = $this->createMock(IShare::class);
3380
+        $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
3381
+        $share->method('getPassword')->willReturn('passwordHash');
3382
+
3383
+        $this->hasher->method('verify')->with('password', 'passwordHash', '')->willReturn(true);
3384
+
3385
+        $this->assertTrue($this->manager->checkPassword($share, 'password'));
3386
+    }
3387
+
3388
+    public function testCheckPasswordUpdateShare(): void {
3389
+        $share = $this->manager->newShare();
3390
+        $share->setShareType(IShare::TYPE_LINK)
3391
+            ->setPassword('passwordHash');
3392
+
3393
+        $this->hasher->method('verify')->with('password', 'passwordHash', '')
3394
+            ->willReturnCallback(function ($pass, $hash, &$newHash) {
3395
+                $newHash = 'newHash';
3396
+
3397
+                return true;
3398
+            });
3399
+
3400
+        $this->defaultProvider->expects($this->once())
3401
+            ->method('update')
3402
+            ->with($this->callback(function (IShare $share) {
3403
+                return $share->getPassword() === 'newHash';
3404
+            }));
3405
+
3406
+        $this->assertTrue($this->manager->checkPassword($share, 'password'));
3407
+    }
3408
+
3409
+
3410
+    public function testUpdateShareCantChangeShareType(): void {
3411
+        $this->expectException(\Exception::class);
3412
+        $this->expectExceptionMessage('Cannot change share type');
3413
+
3414
+        $manager = $this->createManagerMock()
3415
+            ->onlyMethods([
3416
+                'canShare',
3417
+                'getShareById'
3418
+            ])
3419
+            ->getMock();
3420
+
3421
+        $originalShare = $this->manager->newShare();
3422
+        $originalShare->setShareType(IShare::TYPE_GROUP);
3423
+
3424
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3425
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3426
+
3427
+        $share = $this->manager->newShare();
3428
+        $attrs = $this->manager->newShare()->newAttributes();
3429
+        $attrs->setAttribute('app1', 'perm1', true);
3430
+        $share->setProviderId('foo')
3431
+            ->setId('42')
3432
+            ->setShareType(IShare::TYPE_USER);
3433
+
3434
+        $manager->updateShare($share);
3435
+    }
3436
+
3437
+
3438
+    public function testUpdateShareCantChangeRecipientForGroupShare(): void {
3439
+        $this->expectException(\Exception::class);
3440
+        $this->expectExceptionMessage('Can only update recipient on user shares');
3441
+
3442
+        $manager = $this->createManagerMock()
3443
+            ->onlyMethods([
3444
+                'canShare',
3445
+                'getShareById'
3446
+            ])
3447
+            ->getMock();
3448
+
3449
+        $originalShare = $this->manager->newShare();
3450
+        $originalShare->setShareType(IShare::TYPE_GROUP)
3451
+            ->setSharedWith('origGroup');
3452
+
3453
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3454
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3455
+
3456
+        $share = $this->manager->newShare();
3457
+        $share->setProviderId('foo')
3458
+            ->setId('42')
3459
+            ->setShareType(IShare::TYPE_GROUP)
3460
+            ->setSharedWith('newGroup');
3461
+
3462
+        $manager->updateShare($share);
3463
+    }
3464
+
3465
+
3466
+    public function testUpdateShareCantShareWithOwner(): void {
3467
+        $this->expectException(\Exception::class);
3468
+        $this->expectExceptionMessage('Cannot share with the share owner');
3469
+
3470
+        $manager = $this->createManagerMock()
3471
+            ->onlyMethods([
3472
+                'canShare',
3473
+                'getShareById'
3474
+            ])
3475
+            ->getMock();
3476
+
3477
+        $originalShare = $this->manager->newShare();
3478
+        $originalShare->setShareType(IShare::TYPE_USER)
3479
+            ->setSharedWith('sharedWith');
3480
+
3481
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3482
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3483
+
3484
+        $share = $this->manager->newShare();
3485
+        $share->setProviderId('foo')
3486
+            ->setId('42')
3487
+            ->setShareType(IShare::TYPE_USER)
3488
+            ->setSharedWith('newUser')
3489
+            ->setShareOwner('newUser');
3490
+
3491
+        $manager->updateShare($share);
3492
+    }
3493
+
3494
+    public function testUpdateShareUser(): void {
3495
+        $this->userManager->expects($this->any())->method('userExists')->willReturn(true);
3496
+
3497
+        $manager = $this->createManagerMock()
3498
+            ->onlyMethods([
3499
+                'canShare',
3500
+                'getShareById',
3501
+                'generalCreateChecks',
3502
+                'userCreateChecks',
3503
+                'pathCreateChecks',
3504
+            ])
3505
+            ->getMock();
3506
+
3507
+        $originalShare = $this->manager->newShare();
3508
+        $originalShare->setShareType(IShare::TYPE_USER)
3509
+            ->setSharedWith('origUser')
3510
+            ->setPermissions(1);
3511
+
3512
+        $node = $this->createMock(File::class);
3513
+        $node->method('getId')->willReturn(100);
3514
+        $node->method('getPath')->willReturn('/newUser/files/myPath');
3515
+
3516
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3517
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3518
+
3519
+        $share = $this->manager->newShare();
3520
+        $attrs = $this->manager->newShare()->newAttributes();
3521
+        $attrs->setAttribute('app1', 'perm1', true);
3522
+        $share->setProviderId('foo')
3523
+            ->setId('42')
3524
+            ->setShareType(IShare::TYPE_USER)
3525
+            ->setSharedWith('origUser')
3526
+            ->setShareOwner('newUser')
3527
+            ->setSharedBy('sharer')
3528
+            ->setPermissions(31)
3529
+            ->setAttributes($attrs)
3530
+            ->setNode($node);
3531
+
3532
+        $this->defaultProvider->expects($this->once())
3533
+            ->method('update')
3534
+            ->with($share)
3535
+            ->willReturn($share);
3536
+
3537
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3538
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3539
+        $hookListener->expects($this->never())->method('post');
3540
+
3541
+        $this->rootFolder->method('getUserFolder')->with('newUser')->willReturnSelf();
3542
+        $this->rootFolder->method('getRelativePath')->with('/newUser/files/myPath')->willReturn('/myPath');
3543
+
3544
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3545
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener2, 'post');
3546
+        $hookListener2->expects($this->once())->method('post')->with([
3547
+            'itemType' => 'file',
3548
+            'itemSource' => 100,
3549
+            'shareType' => IShare::TYPE_USER,
3550
+            'shareWith' => 'origUser',
3551
+            'uidOwner' => 'sharer',
3552
+            'permissions' => 31,
3553
+            'path' => '/myPath',
3554
+            'attributes' => $attrs->toArray(),
3555
+        ]);
3556
+
3557
+        $manager->updateShare($share);
3558
+    }
3559
+
3560
+    public function testUpdateShareGroup(): void {
3561
+        $manager = $this->createManagerMock()
3562
+            ->onlyMethods([
3563
+                'canShare',
3564
+                'getShareById',
3565
+                'generalCreateChecks',
3566
+                'groupCreateChecks',
3567
+                'pathCreateChecks',
3568
+            ])
3569
+            ->getMock();
3570
+
3571
+        $originalShare = $this->manager->newShare();
3572
+        $originalShare->setShareType(IShare::TYPE_GROUP)
3573
+            ->setSharedWith('origUser')
3574
+            ->setPermissions(31);
3575
+
3576
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3577
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3578
+
3579
+        $node = $this->createMock(File::class);
3580
+
3581
+        $share = $this->manager->newShare();
3582
+        $share->setProviderId('foo')
3583
+            ->setId('42')
3584
+            ->setShareType(IShare::TYPE_GROUP)
3585
+            ->setSharedWith('origUser')
3586
+            ->setShareOwner('owner')
3587
+            ->setNode($node)
3588
+            ->setPermissions(31);
3589
+
3590
+        $this->defaultProvider->expects($this->once())
3591
+            ->method('update')
3592
+            ->with($share)
3593
+            ->willReturn($share);
3594
+
3595
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3596
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3597
+        $hookListener->expects($this->never())->method('post');
3598
+
3599
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3600
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener2, 'post');
3601
+        $hookListener2->expects($this->never())->method('post');
3602
+
3603
+        $manager->updateShare($share);
3604
+    }
3605
+
3606
+    public function testUpdateShareLink(): void {
3607
+        $manager = $this->createManagerMock()
3608
+            ->onlyMethods([
3609
+                'canShare',
3610
+                'getShareById',
3611
+                'generalCreateChecks',
3612
+                'linkCreateChecks',
3613
+                'pathCreateChecks',
3614
+                'verifyPassword',
3615
+                'validateExpirationDateLink',
3616
+            ])
3617
+            ->getMock();
3618
+
3619
+        $originalShare = $this->manager->newShare();
3620
+        $originalShare->setShareType(IShare::TYPE_LINK)
3621
+            ->setPermissions(15);
3622
+
3623
+        $tomorrow = new \DateTime();
3624
+        $tomorrow->setTime(0, 0, 0);
3625
+        $tomorrow->add(new \DateInterval('P1D'));
3626
+
3627
+        $file = $this->createMock(File::class);
3628
+        $file->method('getId')->willReturn(100);
3629
+
3630
+        $share = $this->manager->newShare();
3631
+        $share->setProviderId('foo')
3632
+            ->setId('42')
3633
+            ->setShareType(IShare::TYPE_LINK)
3634
+            ->setToken('token')
3635
+            ->setSharedBy('owner')
3636
+            ->setShareOwner('owner')
3637
+            ->setPassword('password')
3638
+            ->setExpirationDate($tomorrow)
3639
+            ->setNode($file)
3640
+            ->setPermissions(15);
3641
+
3642
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3643
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3644
+        $manager->expects($this->once())->method('validateExpirationDateLink')->with($share);
3645
+        $manager->expects($this->once())->method('verifyPassword')->with('password');
3646
+
3647
+        $this->hasher->expects($this->once())
3648
+            ->method('hash')
3649
+            ->with('password')
3650
+            ->willReturn('hashed');
3651
+
3652
+        $this->defaultProvider->expects($this->once())
3653
+            ->method('update')
3654
+            ->with($share)
3655
+            ->willReturn($share);
3656
+
3657
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3658
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3659
+        $hookListener->expects($this->once())->method('post')->with([
3660
+            'itemType' => 'file',
3661
+            'itemSource' => 100,
3662
+            'date' => $tomorrow,
3663
+            'uidOwner' => 'owner',
3664
+        ]);
3665
+
3666
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3667
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3668
+        $hookListener2->expects($this->once())->method('post')->with([
3669
+            'itemType' => 'file',
3670
+            'itemSource' => 100,
3671
+            'uidOwner' => 'owner',
3672
+            'token' => 'token',
3673
+            'disabled' => false,
3674
+        ]);
3675
+
3676
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
3677
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3678
+        $hookListener3->expects($this->never())->method('post');
3679
+
3680
+
3681
+        $manager->updateShare($share);
3682
+    }
3683
+
3684
+    public function testUpdateShareLinkEnableSendPasswordByTalkWithNoPassword(): void {
3685
+        $this->expectException(\InvalidArgumentException::class);
3686
+        $this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
3687
+
3688
+        $manager = $this->createManagerMock()
3689
+            ->onlyMethods([
3690
+                'canShare',
3691
+                'getShareById',
3692
+                'generalCreateChecks',
3693
+                'linkCreateChecks',
3694
+                'pathCreateChecks',
3695
+                'verifyPassword',
3696
+                'validateExpirationDateLink',
3697
+            ])
3698
+            ->getMock();
3699
+
3700
+        $originalShare = $this->manager->newShare();
3701
+        $originalShare->setShareType(IShare::TYPE_LINK)
3702
+            ->setPermissions(15);
3703
+
3704
+        $tomorrow = new \DateTime();
3705
+        $tomorrow->setTime(0, 0, 0);
3706
+        $tomorrow->add(new \DateInterval('P1D'));
3707
+
3708
+        $file = $this->createMock(File::class);
3709
+        $file->method('getId')->willReturn(100);
3710
+
3711
+        $share = $this->manager->newShare();
3712
+        $share->setProviderId('foo')
3713
+            ->setId('42')
3714
+            ->setShareType(IShare::TYPE_LINK)
3715
+            ->setToken('token')
3716
+            ->setSharedBy('owner')
3717
+            ->setShareOwner('owner')
3718
+            ->setPassword(null)
3719
+            ->setSendPasswordByTalk(true)
3720
+            ->setExpirationDate($tomorrow)
3721
+            ->setNode($file)
3722
+            ->setPermissions(15);
3723
+
3724
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3725
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3726
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
3727
+        $manager->expects($this->once())->method('linkCreateChecks')->with($share);
3728
+        $manager->expects($this->never())->method('verifyPassword');
3729
+        $manager->expects($this->never())->method('pathCreateChecks');
3730
+        $manager->expects($this->never())->method('validateExpirationDateLink');
3731
+
3732
+        $this->hasher->expects($this->never())
3733
+            ->method('hash');
3734
+
3735
+        $this->defaultProvider->expects($this->never())
3736
+            ->method('update');
3737
+
3738
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3739
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3740
+        $hookListener->expects($this->never())->method('post');
3741
+
3742
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3743
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3744
+        $hookListener2->expects($this->never())->method('post');
3745
+
3746
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
3747
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3748
+        $hookListener3->expects($this->never())->method('post');
3749
+
3750
+        $manager->updateShare($share);
3751
+    }
3752
+
3753
+    public function testUpdateShareMail(): void {
3754
+        $manager = $this->createManagerMock()
3755
+            ->onlyMethods([
3756
+                'canShare',
3757
+                'getShareById',
3758
+                'generalCreateChecks',
3759
+                'verifyPassword',
3760
+                'pathCreateChecks',
3761
+                'linkCreateChecks',
3762
+                'validateExpirationDateLink',
3763
+            ])
3764
+            ->getMock();
3765
+
3766
+        $originalShare = $this->manager->newShare();
3767
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
3768
+            ->setPermissions(Constants::PERMISSION_ALL);
3769
+
3770
+        $tomorrow = new \DateTime();
3771
+        $tomorrow->setTime(0, 0, 0);
3772
+        $tomorrow->add(new \DateInterval('P1D'));
3773
+
3774
+        $file = $this->createMock(File::class);
3775
+        $file->method('getId')->willReturn(100);
3776
+
3777
+        $share = $this->manager->newShare();
3778
+        $share->setProviderId('foo')
3779
+            ->setId('42')
3780
+            ->setShareType(IShare::TYPE_EMAIL)
3781
+            ->setToken('token')
3782
+            ->setSharedBy('owner')
3783
+            ->setShareOwner('owner')
3784
+            ->setPassword('password')
3785
+            ->setExpirationDate($tomorrow)
3786
+            ->setNode($file)
3787
+            ->setPermissions(Constants::PERMISSION_ALL);
3788
+
3789
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3790
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3791
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
3792
+        $manager->expects($this->once())->method('verifyPassword')->with('password');
3793
+        $manager->expects($this->once())->method('pathCreateChecks')->with($file);
3794
+        $manager->expects($this->once())->method('linkCreateChecks');
3795
+        $manager->expects($this->once())->method('validateExpirationDateLink');
3796
+
3797
+        $this->hasher->expects($this->once())
3798
+            ->method('hash')
3799
+            ->with('password')
3800
+            ->willReturn('hashed');
3801
+
3802
+        $this->defaultProvider->expects($this->once())
3803
+            ->method('update')
3804
+            ->with($share, 'password')
3805
+            ->willReturn($share);
3806
+
3807
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3808
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3809
+        $hookListener->expects($this->once())->method('post')->with([
3810
+            'itemType' => 'file',
3811
+            'itemSource' => 100,
3812
+            'date' => $tomorrow,
3813
+            'uidOwner' => 'owner',
3814
+        ]);
3815
+
3816
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3817
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3818
+        $hookListener2->expects($this->once())->method('post')->with([
3819
+            'itemType' => 'file',
3820
+            'itemSource' => 100,
3821
+            'uidOwner' => 'owner',
3822
+            'token' => 'token',
3823
+            'disabled' => false,
3824
+        ]);
3825
+
3826
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
3827
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3828
+        $hookListener3->expects($this->never())->method('post');
3829
+
3830
+        $manager->updateShare($share);
3831
+    }
3832
+
3833
+    public function testUpdateShareMailEnableSendPasswordByTalk(): void {
3834
+        $manager = $this->createManagerMock()
3835
+            ->onlyMethods([
3836
+                'canShare',
3837
+                'getShareById',
3838
+                'generalCreateChecks',
3839
+                'verifyPassword',
3840
+                'pathCreateChecks',
3841
+                'linkCreateChecks',
3842
+                'validateExpirationDateLink',
3843
+            ])
3844
+            ->getMock();
3845
+
3846
+        $originalShare = $this->manager->newShare();
3847
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
3848
+            ->setPermissions(Constants::PERMISSION_ALL)
3849
+            ->setPassword(null)
3850
+            ->setSendPasswordByTalk(false);
3851
+
3852
+        $tomorrow = new \DateTime();
3853
+        $tomorrow->setTime(0, 0, 0);
3854
+        $tomorrow->add(new \DateInterval('P1D'));
3855
+
3856
+        $file = $this->createMock(File::class);
3857
+        $file->method('getId')->willReturn(100);
3858
+
3859
+        $share = $this->manager->newShare();
3860
+        $share->setProviderId('foo')
3861
+            ->setId('42')
3862
+            ->setShareType(IShare::TYPE_EMAIL)
3863
+            ->setToken('token')
3864
+            ->setSharedBy('owner')
3865
+            ->setShareOwner('owner')
3866
+            ->setPassword('password')
3867
+            ->setSendPasswordByTalk(true)
3868
+            ->setExpirationDate($tomorrow)
3869
+            ->setNode($file)
3870
+            ->setPermissions(Constants::PERMISSION_ALL);
3871
+
3872
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3873
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3874
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
3875
+        $manager->expects($this->once())->method('verifyPassword')->with('password');
3876
+        $manager->expects($this->once())->method('pathCreateChecks')->with($file);
3877
+        $manager->expects($this->once())->method('linkCreateChecks');
3878
+        $manager->expects($this->once())->method('validateExpirationDateLink');
3879
+
3880
+        $this->hasher->expects($this->once())
3881
+            ->method('hash')
3882
+            ->with('password')
3883
+            ->willReturn('hashed');
3884
+
3885
+        $this->defaultProvider->expects($this->once())
3886
+            ->method('update')
3887
+            ->with($share, 'password')
3888
+            ->willReturn($share);
3889
+
3890
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3891
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3892
+        $hookListener->expects($this->once())->method('post')->with([
3893
+            'itemType' => 'file',
3894
+            'itemSource' => 100,
3895
+            'date' => $tomorrow,
3896
+            'uidOwner' => 'owner',
3897
+        ]);
3898
+
3899
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3900
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3901
+        $hookListener2->expects($this->once())->method('post')->with([
3902
+            'itemType' => 'file',
3903
+            'itemSource' => 100,
3904
+            'uidOwner' => 'owner',
3905
+            'token' => 'token',
3906
+            'disabled' => false,
3907
+        ]);
3908
+
3909
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
3910
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3911
+        $hookListener3->expects($this->never())->method('post');
3912
+
3913
+        $manager->updateShare($share);
3914
+    }
3915
+
3916
+    public function testUpdateShareMailEnableSendPasswordByTalkWithDifferentPassword(): void {
3917
+        $manager = $this->createManagerMock()
3918
+            ->onlyMethods([
3919
+                'canShare',
3920
+                'getShareById',
3921
+                'generalCreateChecks',
3922
+                'verifyPassword',
3923
+                'pathCreateChecks',
3924
+                'linkCreateChecks',
3925
+                'validateExpirationDateLink',
3926
+            ])
3927
+            ->getMock();
3928
+
3929
+        $originalShare = $this->manager->newShare();
3930
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
3931
+            ->setPermissions(Constants::PERMISSION_ALL)
3932
+            ->setPassword('anotherPasswordHash')
3933
+            ->setSendPasswordByTalk(false);
3934
+
3935
+        $tomorrow = new \DateTime();
3936
+        $tomorrow->setTime(0, 0, 0);
3937
+        $tomorrow->add(new \DateInterval('P1D'));
3938
+
3939
+        $file = $this->createMock(File::class);
3940
+        $file->method('getId')->willReturn(100);
3941
+
3942
+        $share = $this->manager->newShare();
3943
+        $share->setProviderId('foo')
3944
+            ->setId('42')
3945
+            ->setShareType(IShare::TYPE_EMAIL)
3946
+            ->setToken('token')
3947
+            ->setSharedBy('owner')
3948
+            ->setShareOwner('owner')
3949
+            ->setPassword('password')
3950
+            ->setSendPasswordByTalk(true)
3951
+            ->setExpirationDate($tomorrow)
3952
+            ->setNode($file)
3953
+            ->setPermissions(Constants::PERMISSION_ALL);
3954
+
3955
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
3956
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
3957
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
3958
+        $manager->expects($this->once())->method('verifyPassword')->with('password');
3959
+        $manager->expects($this->once())->method('pathCreateChecks')->with($file);
3960
+        $manager->expects($this->once())->method('linkCreateChecks');
3961
+        $manager->expects($this->once())->method('validateExpirationDateLink');
3962
+
3963
+        $this->hasher->expects($this->once())
3964
+            ->method('verify')
3965
+            ->with('password', 'anotherPasswordHash')
3966
+            ->willReturn(false);
3967
+
3968
+        $this->hasher->expects($this->once())
3969
+            ->method('hash')
3970
+            ->with('password')
3971
+            ->willReturn('hashed');
3972
+
3973
+        $this->defaultProvider->expects($this->once())
3974
+            ->method('update')
3975
+            ->with($share, 'password')
3976
+            ->willReturn($share);
3977
+
3978
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
3979
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
3980
+        $hookListener->expects($this->once())->method('post')->with([
3981
+            'itemType' => 'file',
3982
+            'itemSource' => 100,
3983
+            'date' => $tomorrow,
3984
+            'uidOwner' => 'owner',
3985
+        ]);
3986
+
3987
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
3988
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
3989
+        $hookListener2->expects($this->once())->method('post')->with([
3990
+            'itemType' => 'file',
3991
+            'itemSource' => 100,
3992
+            'uidOwner' => 'owner',
3993
+            'token' => 'token',
3994
+            'disabled' => false,
3995
+        ]);
3996
+
3997
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
3998
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
3999
+        $hookListener3->expects($this->never())->method('post');
4000
+
4001
+        $manager->updateShare($share);
4002
+    }
4003
+
4004
+    public function testUpdateShareMailEnableSendPasswordByTalkWithNoPassword(): void {
4005
+        $this->expectException(\InvalidArgumentException::class);
4006
+        $this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
4007
+
4008
+        $manager = $this->createManagerMock()
4009
+            ->onlyMethods([
4010
+                'canShare',
4011
+                'getShareById',
4012
+                'generalCreateChecks',
4013
+                'verifyPassword',
4014
+                'pathCreateChecks',
4015
+                'linkCreateChecks',
4016
+                'validateExpirationDateLink',
4017
+            ])
4018
+            ->getMock();
4019
+
4020
+        $originalShare = $this->manager->newShare();
4021
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
4022
+            ->setPermissions(Constants::PERMISSION_ALL)
4023
+            ->setPassword(null)
4024
+            ->setSendPasswordByTalk(false);
4025
+
4026
+        $tomorrow = new \DateTime();
4027
+        $tomorrow->setTime(0, 0, 0);
4028
+        $tomorrow->add(new \DateInterval('P1D'));
4029
+
4030
+        $file = $this->createMock(File::class);
4031
+        $file->method('getId')->willReturn(100);
4032
+
4033
+        $share = $this->manager->newShare();
4034
+        $share->setProviderId('foo')
4035
+            ->setId('42')
4036
+            ->setShareType(IShare::TYPE_EMAIL)
4037
+            ->setToken('token')
4038
+            ->setSharedBy('owner')
4039
+            ->setShareOwner('owner')
4040
+            ->setPassword(null)
4041
+            ->setSendPasswordByTalk(true)
4042
+            ->setExpirationDate($tomorrow)
4043
+            ->setNode($file)
4044
+            ->setPermissions(Constants::PERMISSION_ALL);
4045
+
4046
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
4047
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4048
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
4049
+        $manager->expects($this->never())->method('verifyPassword');
4050
+        $manager->expects($this->never())->method('pathCreateChecks');
4051
+        $manager->expects($this->once())->method('linkCreateChecks');
4052
+        $manager->expects($this->never())->method('validateExpirationDateLink');
4053
+
4054
+        // If the password is empty, we have nothing to hash
4055
+        $this->hasher->expects($this->never())
4056
+            ->method('hash');
4057
+
4058
+        $this->defaultProvider->expects($this->never())
4059
+            ->method('update');
4060
+
4061
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
4062
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4063
+        $hookListener->expects($this->never())->method('post');
4064
+
4065
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
4066
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4067
+        $hookListener2->expects($this->never())->method('post');
4068
+
4069
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
4070
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4071
+        $hookListener3->expects($this->never())->method('post');
4072
+
4073
+        $manager->updateShare($share);
4074
+    }
4075
+
4076
+
4077
+    public function testUpdateShareMailEnableSendPasswordByTalkRemovingPassword(): void {
4078
+        $this->expectException(\InvalidArgumentException::class);
4079
+        $this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
4080
+
4081
+        $manager = $this->createManagerMock()
4082
+            ->onlyMethods([
4083
+                'canShare',
4084
+                'getShareById',
4085
+                'generalCreateChecks',
4086
+                'verifyPassword',
4087
+                'pathCreateChecks',
4088
+                'linkCreateChecks',
4089
+                'validateExpirationDateLink',
4090
+            ])
4091
+            ->getMock();
4092
+
4093
+        $originalShare = $this->manager->newShare();
4094
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
4095
+            ->setPermissions(Constants::PERMISSION_ALL)
4096
+            ->setPassword('passwordHash')
4097
+            ->setSendPasswordByTalk(false);
4098
+
4099
+        $tomorrow = new \DateTime();
4100
+        $tomorrow->setTime(0, 0, 0);
4101
+        $tomorrow->add(new \DateInterval('P1D'));
4102
+
4103
+        $file = $this->createMock(File::class);
4104
+        $file->method('getId')->willReturn(100);
4105
+
4106
+        $share = $this->manager->newShare();
4107
+        $share->setProviderId('foo')
4108
+            ->setId('42')
4109
+            ->setShareType(IShare::TYPE_EMAIL)
4110
+            ->setToken('token')
4111
+            ->setSharedBy('owner')
4112
+            ->setShareOwner('owner')
4113
+            ->setPassword(null)
4114
+            ->setSendPasswordByTalk(true)
4115
+            ->setExpirationDate($tomorrow)
4116
+            ->setNode($file)
4117
+            ->setPermissions(Constants::PERMISSION_ALL);
4118
+
4119
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
4120
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4121
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
4122
+        $manager->expects($this->once())->method('verifyPassword');
4123
+        $manager->expects($this->never())->method('pathCreateChecks');
4124
+        $manager->expects($this->once())->method('linkCreateChecks');
4125
+        $manager->expects($this->never())->method('validateExpirationDateLink');
4126
+
4127
+        // If the password is empty, we have nothing to hash
4128
+        $this->hasher->expects($this->never())
4129
+            ->method('hash');
4130
+
4131
+        $this->defaultProvider->expects($this->never())
4132
+            ->method('update');
4133
+
4134
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
4135
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4136
+        $hookListener->expects($this->never())->method('post');
4137
+
4138
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
4139
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4140
+        $hookListener2->expects($this->never())->method('post');
4141
+
4142
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
4143
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4144
+        $hookListener3->expects($this->never())->method('post');
4145
+
4146
+        $manager->updateShare($share);
4147
+    }
4148
+
4149
+
4150
+    public function testUpdateShareMailEnableSendPasswordByTalkRemovingPasswordWithEmptyString(): void {
4151
+        $this->expectException(\InvalidArgumentException::class);
4152
+        $this->expectExceptionMessage('Cannot enable sending the password by Talk with an empty password');
4153
+
4154
+        $manager = $this->createManagerMock()
4155
+            ->onlyMethods([
4156
+                'canShare',
4157
+                'getShareById',
4158
+                'generalCreateChecks',
4159
+                'verifyPassword',
4160
+                'pathCreateChecks',
4161
+                'linkCreateChecks',
4162
+                'validateExpirationDateLink',
4163
+            ])
4164
+            ->getMock();
4165
+
4166
+        $originalShare = $this->manager->newShare();
4167
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
4168
+            ->setPermissions(Constants::PERMISSION_ALL)
4169
+            ->setPassword('passwordHash')
4170
+            ->setSendPasswordByTalk(false);
4171
+
4172
+        $tomorrow = new \DateTime();
4173
+        $tomorrow->setTime(0, 0, 0);
4174
+        $tomorrow->add(new \DateInterval('P1D'));
4175
+
4176
+        $file = $this->createMock(File::class);
4177
+        $file->method('getId')->willReturn(100);
4178
+
4179
+        $share = $this->manager->newShare();
4180
+        $share->setProviderId('foo')
4181
+            ->setId('42')
4182
+            ->setShareType(IShare::TYPE_EMAIL)
4183
+            ->setToken('token')
4184
+            ->setSharedBy('owner')
4185
+            ->setShareOwner('owner')
4186
+            ->setPassword('')
4187
+            ->setSendPasswordByTalk(true)
4188
+            ->setExpirationDate($tomorrow)
4189
+            ->setNode($file)
4190
+            ->setPermissions(Constants::PERMISSION_ALL);
4191
+
4192
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
4193
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4194
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
4195
+        $manager->expects($this->once())->method('verifyPassword');
4196
+        $manager->expects($this->never())->method('pathCreateChecks');
4197
+        $manager->expects($this->once())->method('linkCreateChecks');
4198
+        $manager->expects($this->never())->method('validateExpirationDateLink');
4199
+
4200
+        // If the password is empty, we have nothing to hash
4201
+        $this->hasher->expects($this->never())
4202
+            ->method('hash');
4203
+
4204
+        $this->defaultProvider->expects($this->never())
4205
+            ->method('update');
4206
+
4207
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
4208
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4209
+        $hookListener->expects($this->never())->method('post');
4210
+
4211
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
4212
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4213
+        $hookListener2->expects($this->never())->method('post');
4214
+
4215
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
4216
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4217
+        $hookListener3->expects($this->never())->method('post');
4218
+
4219
+        $manager->updateShare($share);
4220
+    }
4221
+
4222
+
4223
+    public function testUpdateShareMailEnableSendPasswordByTalkWithPreviousPassword(): void {
4224
+        $this->expectException(\InvalidArgumentException::class);
4225
+        $this->expectExceptionMessage('Cannot enable sending the password by Talk without setting a new password');
4226
+
4227
+        $manager = $this->createManagerMock()
4228
+            ->onlyMethods([
4229
+                'canShare',
4230
+                'getShareById',
4231
+                'generalCreateChecks',
4232
+                'verifyPassword',
4233
+                'pathCreateChecks',
4234
+                'linkCreateChecks',
4235
+                'validateExpirationDateLink',
4236
+            ])
4237
+            ->getMock();
4238
+
4239
+        $originalShare = $this->manager->newShare();
4240
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
4241
+            ->setPermissions(Constants::PERMISSION_ALL)
4242
+            ->setPassword('password')
4243
+            ->setSendPasswordByTalk(false);
4244
+
4245
+        $tomorrow = new \DateTime();
4246
+        $tomorrow->setTime(0, 0, 0);
4247
+        $tomorrow->add(new \DateInterval('P1D'));
4248
+
4249
+        $file = $this->createMock(File::class);
4250
+        $file->method('getId')->willReturn(100);
4251
+
4252
+        $share = $this->manager->newShare();
4253
+        $share->setProviderId('foo')
4254
+            ->setId('42')
4255
+            ->setShareType(IShare::TYPE_EMAIL)
4256
+            ->setToken('token')
4257
+            ->setSharedBy('owner')
4258
+            ->setShareOwner('owner')
4259
+            ->setPassword('password')
4260
+            ->setSendPasswordByTalk(true)
4261
+            ->setExpirationDate($tomorrow)
4262
+            ->setNode($file)
4263
+            ->setPermissions(Constants::PERMISSION_ALL);
4264
+
4265
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
4266
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4267
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
4268
+        $manager->expects($this->never())->method('verifyPassword');
4269
+        $manager->expects($this->never())->method('pathCreateChecks');
4270
+        $manager->expects($this->once())->method('linkCreateChecks');
4271
+        $manager->expects($this->never())->method('validateExpirationDateLink');
4272
+
4273
+        // If the old & new passwords are the same, we don't do anything
4274
+        $this->hasher->expects($this->never())
4275
+            ->method('verify');
4276
+        $this->hasher->expects($this->never())
4277
+            ->method('hash');
4278
+
4279
+        $this->defaultProvider->expects($this->never())
4280
+            ->method('update');
4281
+
4282
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
4283
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4284
+        $hookListener->expects($this->never())->method('post');
4285
+
4286
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
4287
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4288
+        $hookListener2->expects($this->never())->method('post');
4289
+
4290
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
4291
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4292
+        $hookListener3->expects($this->never())->method('post');
4293
+
4294
+        $manager->updateShare($share);
4295
+    }
4296
+
4297
+    public function testUpdateShareMailDisableSendPasswordByTalkWithPreviousPassword(): void {
4298
+        $this->expectException(\InvalidArgumentException::class);
4299
+        $this->expectExceptionMessage('Cannot disable sending the password by Talk without setting a new password');
4300
+
4301
+        $manager = $this->createManagerMock()
4302
+            ->onlyMethods([
4303
+                'canShare',
4304
+                'getShareById',
4305
+                'generalCreateChecks',
4306
+                'verifyPassword',
4307
+                'pathCreateChecks',
4308
+                'linkCreateChecks',
4309
+                'validateExpirationDateLink',
4310
+            ])
4311
+            ->getMock();
4312
+
4313
+        $originalShare = $this->manager->newShare();
4314
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
4315
+            ->setPermissions(Constants::PERMISSION_ALL)
4316
+            ->setPassword('passwordHash')
4317
+            ->setSendPasswordByTalk(true);
4318
+
4319
+        $tomorrow = new \DateTime();
4320
+        $tomorrow->setTime(0, 0, 0);
4321
+        $tomorrow->add(new \DateInterval('P1D'));
4322
+
4323
+        $file = $this->createMock(File::class);
4324
+        $file->method('getId')->willReturn(100);
4325
+
4326
+        $share = $this->manager->newShare();
4327
+        $share->setProviderId('foo')
4328
+            ->setId('42')
4329
+            ->setShareType(IShare::TYPE_EMAIL)
4330
+            ->setToken('token')
4331
+            ->setSharedBy('owner')
4332
+            ->setShareOwner('owner')
4333
+            ->setPassword('passwordHash')
4334
+            ->setSendPasswordByTalk(false)
4335
+            ->setExpirationDate($tomorrow)
4336
+            ->setNode($file)
4337
+            ->setPermissions(Constants::PERMISSION_ALL);
4338
+
4339
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
4340
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4341
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
4342
+        $manager->expects($this->never())->method('verifyPassword');
4343
+        $manager->expects($this->never())->method('pathCreateChecks');
4344
+        $manager->expects($this->once())->method('linkCreateChecks');
4345
+        $manager->expects($this->never())->method('validateExpirationDateLink');
4346
+
4347
+        // If the old & new passwords are the same, we don't do anything
4348
+        $this->hasher->expects($this->never())
4349
+            ->method('verify');
4350
+        $this->hasher->expects($this->never())
4351
+            ->method('hash');
4352
+
4353
+        $this->defaultProvider->expects($this->never())
4354
+            ->method('update');
4355
+
4356
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
4357
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4358
+        $hookListener->expects($this->never())->method('post');
4359
+
4360
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
4361
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4362
+        $hookListener2->expects($this->never())->method('post');
4363
+
4364
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
4365
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4366
+        $hookListener3->expects($this->never())->method('post');
4367
+
4368
+        $manager->updateShare($share);
4369
+    }
4370
+
4371
+    public function testUpdateShareMailDisableSendPasswordByTalkWithoutChangingPassword(): void {
4372
+        $this->expectException(\InvalidArgumentException::class);
4373
+        $this->expectExceptionMessage('Cannot disable sending the password by Talk without setting a new password');
4374
+
4375
+        $manager = $this->createManagerMock()
4376
+            ->onlyMethods([
4377
+                'canShare',
4378
+                'getShareById',
4379
+                'generalCreateChecks',
4380
+                'verifyPassword',
4381
+                'pathCreateChecks',
4382
+                'linkCreateChecks',
4383
+                'validateExpirationDateLink',
4384
+            ])
4385
+            ->getMock();
4386
+
4387
+        $originalShare = $this->manager->newShare();
4388
+        $originalShare->setShareType(IShare::TYPE_EMAIL)
4389
+            ->setPermissions(Constants::PERMISSION_ALL)
4390
+            ->setPassword('passwordHash')
4391
+            ->setSendPasswordByTalk(true);
4392
+
4393
+        $tomorrow = new \DateTime();
4394
+        $tomorrow->setTime(0, 0, 0);
4395
+        $tomorrow->add(new \DateInterval('P1D'));
4396
+
4397
+        $file = $this->createMock(File::class);
4398
+        $file->method('getId')->willReturn(100);
4399
+
4400
+        $share = $this->manager->newShare();
4401
+        $share->setProviderId('foo')
4402
+            ->setId('42')
4403
+            ->setShareType(IShare::TYPE_EMAIL)
4404
+            ->setToken('token')
4405
+            ->setSharedBy('owner')
4406
+            ->setShareOwner('owner')
4407
+            ->setPassword('passwordHash')
4408
+            ->setSendPasswordByTalk(false)
4409
+            ->setExpirationDate($tomorrow)
4410
+            ->setNode($file)
4411
+            ->setPermissions(Constants::PERMISSION_ALL);
4412
+
4413
+        $manager->expects($this->once())->method('canShare')->willReturn(true);
4414
+        $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
4415
+        $manager->expects($this->once())->method('generalCreateChecks')->with($share);
4416
+        $manager->expects($this->never())->method('verifyPassword');
4417
+        $manager->expects($this->never())->method('pathCreateChecks');
4418
+        $manager->expects($this->once())->method('linkCreateChecks');
4419
+        $manager->expects($this->never())->method('validateExpirationDateLink');
4420
+
4421
+        // If the old & new passwords are the same, we don't do anything
4422
+        $this->hasher->expects($this->never())
4423
+            ->method('verify');
4424
+        $this->hasher->expects($this->never())
4425
+            ->method('hash');
4426
+
4427
+        $this->defaultProvider->expects($this->never())
4428
+            ->method('update');
4429
+
4430
+        $hookListener = $this->createMock(DummyShareManagerListener::class);
4431
+        Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListener, 'post');
4432
+        $hookListener->expects($this->never())->method('post');
4433 4433
 
4434
-		$hookListener2 = $this->createMock(DummyShareManagerListener::class);
4435
-		Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4436
-		$hookListener2->expects($this->never())->method('post');
4434
+        $hookListener2 = $this->createMock(DummyShareManagerListener::class);
4435
+        Util::connectHook('OCP\Share', 'post_update_password', $hookListener2, 'post');
4436
+        $hookListener2->expects($this->never())->method('post');
4437 4437
 
4438
-		$hookListener3 = $this->createMock(DummyShareManagerListener::class);
4439
-		Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4440
-		$hookListener3->expects($this->never())->method('post');
4438
+        $hookListener3 = $this->createMock(DummyShareManagerListener::class);
4439
+        Util::connectHook('OCP\Share', 'post_update_permissions', $hookListener3, 'post');
4440
+        $hookListener3->expects($this->never())->method('post');
4441 4441
 
4442
-		$manager->updateShare($share);
4443
-	}
4442
+        $manager->updateShare($share);
4443
+    }
4444 4444
 
4445
-	public function testMoveShareLink(): void {
4446
-		$this->expectException(\InvalidArgumentException::class);
4447
-		$this->expectExceptionMessage('Cannot change target of link share');
4445
+    public function testMoveShareLink(): void {
4446
+        $this->expectException(\InvalidArgumentException::class);
4447
+        $this->expectExceptionMessage('Cannot change target of link share');
4448 4448
 
4449
-		$share = $this->manager->newShare();
4450
-		$share->setShareType(IShare::TYPE_LINK);
4449
+        $share = $this->manager->newShare();
4450
+        $share->setShareType(IShare::TYPE_LINK);
4451 4451
 
4452
-		$recipient = $this->createMock(IUser::class);
4452
+        $recipient = $this->createMock(IUser::class);
4453 4453
 
4454
-		$this->manager->moveShare($share, $recipient);
4455
-	}
4454
+        $this->manager->moveShare($share, $recipient);
4455
+    }
4456 4456
 
4457 4457
 
4458
-	public function testMoveShareUserNotRecipient(): void {
4459
-		$this->expectException(\InvalidArgumentException::class);
4460
-		$this->expectExceptionMessage('Invalid share recipient');
4458
+    public function testMoveShareUserNotRecipient(): void {
4459
+        $this->expectException(\InvalidArgumentException::class);
4460
+        $this->expectExceptionMessage('Invalid share recipient');
4461 4461
 
4462
-		$share = $this->manager->newShare();
4463
-		$share->setShareType(IShare::TYPE_USER);
4464
-
4465
-		$share->setSharedWith('sharedWith');
4462
+        $share = $this->manager->newShare();
4463
+        $share->setShareType(IShare::TYPE_USER);
4464
+
4465
+        $share->setSharedWith('sharedWith');
4466 4466
 
4467
-		$this->manager->moveShare($share, 'recipient');
4468
-	}
4467
+        $this->manager->moveShare($share, 'recipient');
4468
+    }
4469 4469
 
4470
-	public function testMoveShareUser(): void {
4471
-		$share = $this->manager->newShare();
4472
-		$share->setShareType(IShare::TYPE_USER)
4473
-			->setId('42')
4474
-			->setProviderId('foo');
4470
+    public function testMoveShareUser(): void {
4471
+        $share = $this->manager->newShare();
4472
+        $share->setShareType(IShare::TYPE_USER)
4473
+            ->setId('42')
4474
+            ->setProviderId('foo');
4475 4475
 
4476
-		$share->setSharedWith('recipient');
4476
+        $share->setSharedWith('recipient');
4477 4477
 
4478
-		$this->defaultProvider->method('move')->with($share, 'recipient')->willReturnArgument(0);
4478
+        $this->defaultProvider->method('move')->with($share, 'recipient')->willReturnArgument(0);
4479 4479
 
4480
-		$this->manager->moveShare($share, 'recipient');
4481
-		$this->addToAssertionCount(1);
4482
-	}
4480
+        $this->manager->moveShare($share, 'recipient');
4481
+        $this->addToAssertionCount(1);
4482
+    }
4483 4483
 
4484 4484
 
4485
-	public function testMoveShareGroupNotRecipient(): void {
4486
-		$this->expectException(\InvalidArgumentException::class);
4487
-		$this->expectExceptionMessage('Invalid share recipient');
4485
+    public function testMoveShareGroupNotRecipient(): void {
4486
+        $this->expectException(\InvalidArgumentException::class);
4487
+        $this->expectExceptionMessage('Invalid share recipient');
4488 4488
 
4489
-		$share = $this->manager->newShare();
4490
-		$share->setShareType(IShare::TYPE_GROUP);
4489
+        $share = $this->manager->newShare();
4490
+        $share->setShareType(IShare::TYPE_GROUP);
4491 4491
 
4492
-		$sharedWith = $this->createMock(IGroup::class);
4493
-		$share->setSharedWith('shareWith');
4492
+        $sharedWith = $this->createMock(IGroup::class);
4493
+        $share->setSharedWith('shareWith');
4494 4494
 
4495
-		$recipient = $this->createMock(IUser::class);
4496
-		$sharedWith->method('inGroup')->with($recipient)->willReturn(false);
4495
+        $recipient = $this->createMock(IUser::class);
4496
+        $sharedWith->method('inGroup')->with($recipient)->willReturn(false);
4497 4497
 
4498
-		$this->groupManager->method('get')->with('shareWith')->willReturn($sharedWith);
4499
-		$this->userManager->method('get')->with('recipient')->willReturn($recipient);
4500
-
4501
-		$this->manager->moveShare($share, 'recipient');
4502
-	}
4498
+        $this->groupManager->method('get')->with('shareWith')->willReturn($sharedWith);
4499
+        $this->userManager->method('get')->with('recipient')->willReturn($recipient);
4500
+
4501
+        $this->manager->moveShare($share, 'recipient');
4502
+    }
4503 4503
 
4504 4504
 
4505
-	public function testMoveShareGroupNull(): void {
4506
-		$this->expectException(\InvalidArgumentException::class);
4507
-		$this->expectExceptionMessage('Group "shareWith" does not exist');
4505
+    public function testMoveShareGroupNull(): void {
4506
+        $this->expectException(\InvalidArgumentException::class);
4507
+        $this->expectExceptionMessage('Group "shareWith" does not exist');
4508 4508
 
4509
-		$share = $this->manager->newShare();
4510
-		$share->setShareType(IShare::TYPE_GROUP);
4511
-		$share->setSharedWith('shareWith');
4509
+        $share = $this->manager->newShare();
4510
+        $share->setShareType(IShare::TYPE_GROUP);
4511
+        $share->setSharedWith('shareWith');
4512 4512
 
4513
-		$recipient = $this->createMock(IUser::class);
4513
+        $recipient = $this->createMock(IUser::class);
4514 4514
 
4515
-		$this->groupManager->method('get')->with('shareWith')->willReturn(null);
4516
-		$this->userManager->method('get')->with('recipient')->willReturn($recipient);
4515
+        $this->groupManager->method('get')->with('shareWith')->willReturn(null);
4516
+        $this->userManager->method('get')->with('recipient')->willReturn($recipient);
4517 4517
 
4518
-		$this->manager->moveShare($share, 'recipient');
4519
-	}
4518
+        $this->manager->moveShare($share, 'recipient');
4519
+    }
4520 4520
 
4521
-	public function testMoveShareGroup(): void {
4522
-		$share = $this->manager->newShare();
4523
-		$share->setShareType(IShare::TYPE_GROUP)
4524
-			->setId('42')
4525
-			->setProviderId('foo');
4521
+    public function testMoveShareGroup(): void {
4522
+        $share = $this->manager->newShare();
4523
+        $share->setShareType(IShare::TYPE_GROUP)
4524
+            ->setId('42')
4525
+            ->setProviderId('foo');
4526 4526
 
4527
-		$group = $this->createMock(IGroup::class);
4528
-		$share->setSharedWith('group');
4527
+        $group = $this->createMock(IGroup::class);
4528
+        $share->setSharedWith('group');
4529 4529
 
4530
-		$recipient = $this->createMock(IUser::class);
4531
-		$group->method('inGroup')->with($recipient)->willReturn(true);
4530
+        $recipient = $this->createMock(IUser::class);
4531
+        $group->method('inGroup')->with($recipient)->willReturn(true);
4532 4532
 
4533
-		$this->groupManager->method('get')->with('group')->willReturn($group);
4534
-		$this->userManager->method('get')->with('recipient')->willReturn($recipient);
4533
+        $this->groupManager->method('get')->with('group')->willReturn($group);
4534
+        $this->userManager->method('get')->with('recipient')->willReturn($recipient);
4535 4535
 
4536
-		$this->defaultProvider->method('move')->with($share, 'recipient')->willReturnArgument(0);
4536
+        $this->defaultProvider->method('move')->with($share, 'recipient')->willReturnArgument(0);
4537 4537
 
4538
-		$this->manager->moveShare($share, 'recipient');
4539
-		$this->addToAssertionCount(1);
4540
-	}
4538
+        $this->manager->moveShare($share, 'recipient');
4539
+        $this->addToAssertionCount(1);
4540
+    }
4541 4541
 
4542
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataTestShareProviderExists')]
4543
-	public function testShareProviderExists($shareType, $expected): void {
4544
-		$factory = $this->getMockBuilder('OCP\Share\IProviderFactory')->getMock();
4545
-		$factory->expects($this->any())->method('getProviderForType')
4546
-			->willReturnCallback(function ($id) {
4547
-				if ($id === IShare::TYPE_USER) {
4548
-					return true;
4549
-				}
4550
-				throw new ProviderException();
4551
-			});
4542
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataTestShareProviderExists')]
4543
+    public function testShareProviderExists($shareType, $expected): void {
4544
+        $factory = $this->getMockBuilder('OCP\Share\IProviderFactory')->getMock();
4545
+        $factory->expects($this->any())->method('getProviderForType')
4546
+            ->willReturnCallback(function ($id) {
4547
+                if ($id === IShare::TYPE_USER) {
4548
+                    return true;
4549
+                }
4550
+                throw new ProviderException();
4551
+            });
4552 4552
 
4553
-		$manager = $this->createManager($factory);
4554
-		$this->assertSame($expected,
4555
-			$manager->shareProviderExists($shareType)
4556
-		);
4557
-	}
4553
+        $manager = $this->createManager($factory);
4554
+        $this->assertSame($expected,
4555
+            $manager->shareProviderExists($shareType)
4556
+        );
4557
+    }
4558 4558
 
4559
-	public static function dataTestShareProviderExists() {
4560
-		return [
4561
-			[IShare::TYPE_USER, true],
4562
-			[42, false],
4563
-		];
4564
-	}
4559
+    public static function dataTestShareProviderExists() {
4560
+        return [
4561
+            [IShare::TYPE_USER, true],
4562
+            [42, false],
4563
+        ];
4564
+    }
4565 4565
 
4566
-	public function testGetSharesInFolder(): void {
4567
-		$factory = new DummyFactory2($this->createMock(IServerContainer::class));
4566
+    public function testGetSharesInFolder(): void {
4567
+        $factory = new DummyFactory2($this->createMock(IServerContainer::class));
4568 4568
 
4569
-		$manager = $this->createManager($factory);
4569
+        $manager = $this->createManager($factory);
4570 4570
 
4571
-		$factory->setProvider($this->defaultProvider);
4572
-		$extraProvider = $this->createMock(IShareProvider::class);
4573
-		$factory->setSecondProvider($extraProvider);
4571
+        $factory->setProvider($this->defaultProvider);
4572
+        $extraProvider = $this->createMock(IShareProvider::class);
4573
+        $factory->setSecondProvider($extraProvider);
4574 4574
 
4575
-		$share1 = $this->createMock(IShare::class);
4576
-		$share2 = $this->createMock(IShare::class);
4577
-		$share3 = $this->createMock(IShare::class);
4578
-		$share4 = $this->createMock(IShare::class);
4575
+        $share1 = $this->createMock(IShare::class);
4576
+        $share2 = $this->createMock(IShare::class);
4577
+        $share3 = $this->createMock(IShare::class);
4578
+        $share4 = $this->createMock(IShare::class);
4579 4579
 
4580
-		$folder = $this->createMock(Folder::class);
4580
+        $folder = $this->createMock(Folder::class);
4581 4581
 
4582
-		$this->defaultProvider->method('getSharesInFolder')
4583
-			->with(
4584
-				$this->equalTo('user'),
4585
-				$this->equalTo($folder),
4586
-				$this->equalTo(false)
4587
-			)->willReturn([
4588
-				1 => [$share1],
4589
-				2 => [$share2],
4590
-			]);
4591
-
4592
-		$extraProvider->method('getSharesInFolder')
4593
-			->with(
4594
-				$this->equalTo('user'),
4595
-				$this->equalTo($folder),
4596
-				$this->equalTo(false)
4597
-			)->willReturn([
4598
-				2 => [$share3],
4599
-				3 => [$share4],
4600
-			]);
4601
-
4602
-		$result = $manager->getSharesInFolder('user', $folder, false);
4603
-
4604
-		$expects = [
4605
-			1 => [$share1],
4606
-			2 => [$share2, $share3],
4607
-			3 => [$share4],
4608
-		];
4609
-
4610
-		$this->assertSame($expects, $result);
4611
-	}
4612
-
4613
-	public function testGetSharesInFolderOwnerless(): void {
4614
-		$factory = new DummyFactory2($this->createMock(IServerContainer::class));
4615
-
4616
-		$manager = $this->createManager($factory);
4617
-
4618
-		$factory->setProvider($this->defaultProvider);
4619
-		$extraProvider = $this->createMock(IShareProviderSupportsAllSharesInFolder::class);
4620
-		$factory->setSecondProvider($extraProvider);
4621
-
4622
-		$share1 = $this->createMock(IShare::class);
4623
-		$share2 = $this->createMock(IShare::class);
4624
-
4625
-		$mount = $this->createMock(IShareOwnerlessMount::class);
4626
-
4627
-		$folder = $this->createMock(Folder::class);
4628
-		$folder
4629
-			->method('getMountPoint')
4630
-			->willReturn($mount);
4631
-
4632
-		$this->defaultProvider
4633
-			->method('getAllSharesInFolder')
4634
-			->with($folder)
4635
-			->willReturn([1 => [$share1]]);
4636
-
4637
-		$extraProvider
4638
-			->method('getAllSharesInFolder')
4639
-			->with($folder)
4640
-			->willReturn([1 => [$share2]]);
4641
-
4642
-		$this->assertSame([
4643
-			1 => [$share1, $share2],
4644
-		], $manager->getSharesInFolder('user', $folder));
4645
-	}
4646
-
4647
-
4648
-	public function testGetAccessList(): void {
4649
-		$factory = new DummyFactory2($this->createMock(IServerContainer::class));
4650
-
4651
-		$manager = $this->createManager($factory);
4652
-
4653
-		$factory->setProvider($this->defaultProvider);
4654
-		$extraProvider = $this->createMock(IShareProvider::class);
4655
-		$factory->setSecondProvider($extraProvider);
4656
-
4657
-		$nodeOwner = $this->createMock(IUser::class);
4658
-		$nodeOwner->expects($this->once())
4659
-			->method('getUID')
4660
-			->willReturn('user1');
4661
-
4662
-		$node = $this->createMock(Node::class);
4663
-		$node->expects($this->once())
4664
-			->method('getOwner')
4665
-			->willReturn($nodeOwner);
4666
-		$node->method('getId')
4667
-			->willReturn(42);
4668
-
4669
-		$userFolder = $this->createMock(Folder::class);
4670
-		$file = $this->createMock(File::class);
4671
-		$folder = $this->createMock(Folder::class);
4672
-
4673
-		$owner = $this->createMock(IUser::class);
4674
-		$owner->expects($this->once())
4675
-			->method('getUID')
4676
-			->willReturn('owner');
4677
-
4678
-		$file->method('getParent')
4679
-			->willReturn($folder);
4680
-		$file->method('getPath')
4681
-			->willReturn('/owner/files/folder/file');
4682
-		$file->method('getOwner')
4683
-			->willReturn($owner);
4684
-		$file->method('getId')
4685
-			->willReturn(23);
4686
-		$folder->method('getParent')
4687
-			->willReturn($userFolder);
4688
-		$folder->method('getPath')
4689
-			->willReturn('/owner/files/folder');
4690
-		$userFolder->method('getFirstNodeById')
4691
-			->with($this->equalTo(42))
4692
-			->willReturn($file);
4693
-		$userFolder->method('getPath')
4694
-			->willReturn('/user1/files');
4695
-
4696
-		$this->userManager->method('userExists')
4697
-			->with($this->equalTo('user1'))
4698
-			->willReturn(true);
4699
-
4700
-		$this->defaultProvider->method('getAccessList')
4701
-			->with(
4702
-				$this->equalTo([$file, $folder]),
4703
-				false
4704
-			)
4705
-			->willReturn([
4706
-				'users' => [
4707
-					'user1',
4708
-					'user2',
4709
-					'user3',
4710
-					'123456',
4711
-				],
4712
-				'public' => true,
4713
-			]);
4714
-
4715
-		$extraProvider->method('getAccessList')
4716
-			->with(
4717
-				$this->equalTo([$file, $folder]),
4718
-				false
4719
-			)
4720
-			->willReturn([
4721
-				'users' => [
4722
-					'user3',
4723
-					'user4',
4724
-					'user5',
4725
-					'234567',
4726
-				],
4727
-				'remote' => true,
4728
-			]);
4729
-
4730
-		$this->rootFolder->method('getUserFolder')
4731
-			->with($this->equalTo('user1'))
4732
-			->willReturn($userFolder);
4733
-
4734
-		$expected = [
4735
-			'users' => ['owner', 'user1', 'user2', 'user3', '123456','user4', 'user5', '234567'],
4736
-			'remote' => true,
4737
-			'public' => true,
4738
-		];
4739
-
4740
-		$result = $manager->getAccessList($node, true, false);
4741
-
4742
-		$this->assertSame($expected['public'], $result['public']);
4743
-		$this->assertSame($expected['remote'], $result['remote']);
4744
-		$this->assertSame($expected['users'], $result['users']);
4745
-	}
4746
-
4747
-	public function testGetAccessListWithCurrentAccess(): void {
4748
-		$factory = new DummyFactory2($this->createMock(IServerContainer::class));
4749
-
4750
-		$manager = $this->createManager($factory);
4751
-
4752
-		$factory->setProvider($this->defaultProvider);
4753
-		$extraProvider = $this->createMock(IShareProvider::class);
4754
-		$factory->setSecondProvider($extraProvider);
4755
-
4756
-		$nodeOwner = $this->createMock(IUser::class);
4757
-		$nodeOwner->expects($this->once())
4758
-			->method('getUID')
4759
-			->willReturn('user1');
4760
-
4761
-		$node = $this->createMock(Node::class);
4762
-		$node->expects($this->once())
4763
-			->method('getOwner')
4764
-			->willReturn($nodeOwner);
4765
-		$node->method('getId')
4766
-			->willReturn(42);
4767
-
4768
-		$userFolder = $this->createMock(Folder::class);
4769
-		$file = $this->createMock(File::class);
4770
-
4771
-		$owner = $this->createMock(IUser::class);
4772
-		$owner->expects($this->once())
4773
-			->method('getUID')
4774
-			->willReturn('owner');
4775
-		$folder = $this->createMock(Folder::class);
4776
-
4777
-		$file->method('getParent')
4778
-			->willReturn($folder);
4779
-		$file->method('getPath')
4780
-			->willReturn('/owner/files/folder/file');
4781
-		$file->method('getOwner')
4782
-			->willReturn($owner);
4783
-		$file->method('getId')
4784
-			->willReturn(23);
4785
-		$folder->method('getParent')
4786
-			->willReturn($userFolder);
4787
-		$folder->method('getPath')
4788
-			->willReturn('/owner/files/folder');
4789
-		$userFolder->method('getFirstNodeById')
4790
-			->with($this->equalTo(42))
4791
-			->willReturn($file);
4792
-		$userFolder->method('getPath')
4793
-			->willReturn('/user1/files');
4794
-
4795
-		$this->userManager->method('userExists')
4796
-			->with($this->equalTo('user1'))
4797
-			->willReturn(true);
4798
-
4799
-		$this->defaultProvider->method('getAccessList')
4800
-			->with(
4801
-				$this->equalTo([$file, $folder]),
4802
-				true
4803
-			)
4804
-			->willReturn([
4805
-				'users' => [
4806
-					'user1' => [],
4807
-					'user2' => [],
4808
-					'user3' => [],
4809
-					'123456' => [],
4810
-				],
4811
-				'public' => true,
4812
-			]);
4813
-
4814
-		$extraProvider->method('getAccessList')
4815
-			->with(
4816
-				$this->equalTo([$file, $folder]),
4817
-				true
4818
-			)
4819
-			->willReturn([
4820
-				'users' => [
4821
-					'user3' => [],
4822
-					'user4' => [],
4823
-					'user5' => [],
4824
-					'234567' => [],
4825
-				],
4826
-				'remote' => [
4827
-					'remote1',
4828
-				],
4829
-			]);
4830
-
4831
-		$this->rootFolder->method('getUserFolder')
4832
-			->with($this->equalTo('user1'))
4833
-			->willReturn($userFolder);
4834
-
4835
-		$expected = [
4836
-			'users' => [
4837
-				'owner' => [
4838
-					'node_id' => 23,
4839
-					'node_path' => '/folder/file'
4840
-				]
4841
-				, 'user1' => [], 'user2' => [], 'user3' => [], '123456' => [], 'user4' => [], 'user5' => [], '234567' => []],
4842
-			'remote' => [
4843
-				'remote1',
4844
-			],
4845
-			'public' => true,
4846
-		];
4847
-
4848
-		$result = $manager->getAccessList($node, true, true);
4849
-
4850
-		$this->assertSame($expected['public'], $result['public']);
4851
-		$this->assertSame($expected['remote'], $result['remote']);
4852
-		$this->assertSame($expected['users'], $result['users']);
4853
-	}
4854
-
4855
-	public function testGetAllShares(): void {
4856
-		$factory = new DummyFactory2($this->createMock(IServerContainer::class));
4857
-
4858
-		$manager = $this->createManager($factory);
4859
-
4860
-		$factory->setProvider($this->defaultProvider);
4861
-		$extraProvider = $this->createMock(IShareProvider::class);
4862
-		$factory->setSecondProvider($extraProvider);
4863
-
4864
-		$share1 = $this->createMock(IShare::class);
4865
-		$share2 = $this->createMock(IShare::class);
4866
-		$share3 = $this->createMock(IShare::class);
4867
-		$share4 = $this->createMock(IShare::class);
4868
-
4869
-		$this->defaultProvider->method('getAllShares')
4870
-			->willReturnCallback(function () use ($share1, $share2) {
4871
-				yield $share1;
4872
-				yield $share2;
4873
-			});
4874
-		$extraProvider->method('getAllShares')
4875
-			->willReturnCallback(function () use ($share3, $share4) {
4876
-				yield $share3;
4877
-				yield $share4;
4878
-			});
4879
-
4880
-		// "yield from", used in "getAllShares()", does not reset the keys, so
4881
-		// "use_keys" has to be disabled to collect all the values while
4882
-		// ignoring the keys returned by the generator.
4883
-		$result = iterator_to_array($manager->getAllShares(), $use_keys = false);
4884
-
4885
-		$expects = [$share1, $share2, $share3, $share4];
4886
-
4887
-		$this->assertSame($expects, $result);
4888
-	}
4889
-
4890
-	public static function dataCurrentUserCanEnumerateTargetUser(): array {
4891
-		return [
4892
-			'Full match guest' => [true, true, false, false, false, false, false, true],
4893
-			'Full match user' => [false, true, false, false, false, false, false, true],
4894
-			'Enumeration off guest' => [true, false, false, false, false, false, false, false],
4895
-			'Enumeration off user' => [false, false, false, false, false, false, false, false],
4896
-			'Enumeration guest' => [true, false, true, false, false, false, false, true],
4897
-			'Enumeration user' => [false, false, true, false, false, false, false, true],
4898
-
4899
-			// Restricted enumerations guests never works
4900
-			'Guest phone' => [true, false, true, true, false, false, false, false],
4901
-			'Guest group' => [true, false, true, false, true, false, false, false],
4902
-			'Guest both' => [true, false, true, true, true, false, false, false],
4903
-
4904
-			// Restricted enumerations users
4905
-			'User phone but not known' => [false, false, true, true, false, false, false, false],
4906
-			'User phone known' => [false, false, true, true, false, true, false, true],
4907
-			'User group but no match' => [false, false, true, false, true, false, false, false],
4908
-			'User group with match' => [false, false, true, false, true, false, true, true],
4909
-		];
4910
-	}
4911
-
4912
-	/**
4913
-	 * @param bool $expected
4914
-	 */
4915
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataCurrentUserCanEnumerateTargetUser')]
4916
-	public function testCurrentUserCanEnumerateTargetUser(bool $currentUserIsGuest, bool $allowEnumerationFullMatch, bool $allowEnumeration, bool $limitEnumerationToPhone, bool $limitEnumerationToGroups, bool $isKnownToUser, bool $haveCommonGroup, bool $expected): void {
4917
-		/** @var IManager|MockObject $manager */
4918
-		$manager = $this->createManagerMock()
4919
-			->onlyMethods([
4920
-				'allowEnumerationFullMatch',
4921
-				'allowEnumeration',
4922
-				'limitEnumerationToPhone',
4923
-				'limitEnumerationToGroups',
4924
-			])
4925
-			->getMock();
4926
-
4927
-		$manager->method('allowEnumerationFullMatch')
4928
-			->willReturn($allowEnumerationFullMatch);
4929
-		$manager->method('allowEnumeration')
4930
-			->willReturn($allowEnumeration);
4931
-		$manager->method('limitEnumerationToPhone')
4932
-			->willReturn($limitEnumerationToPhone);
4933
-		$manager->method('limitEnumerationToGroups')
4934
-			->willReturn($limitEnumerationToGroups);
4935
-
4936
-		$this->knownUserService->method('isKnownToUser')
4937
-			->with('current', 'target')
4938
-			->willReturn($isKnownToUser);
4939
-
4940
-		$currentUser = null;
4941
-		if (!$currentUserIsGuest) {
4942
-			$currentUser = $this->createMock(IUser::class);
4943
-			$currentUser->method('getUID')
4944
-				->willReturn('current');
4945
-		}
4946
-		$targetUser = $this->createMock(IUser::class);
4947
-		$targetUser->method('getUID')
4948
-			->willReturn('target');
4949
-
4950
-		if ($haveCommonGroup) {
4951
-			$this->groupManager->method('getUserGroupIds')
4952
-				->willReturnMap([
4953
-					[$targetUser, ['gid1', 'gid2']],
4954
-					[$currentUser, ['gid2', 'gid3']],
4955
-				]);
4956
-		} else {
4957
-			$this->groupManager->method('getUserGroupIds')
4958
-				->willReturnMap([
4959
-					[$targetUser, ['gid1', 'gid2']],
4960
-					[$currentUser, ['gid3', 'gid4']],
4961
-				]);
4962
-		}
4963
-
4964
-		$this->assertSame($expected, $manager->currentUserCanEnumerateTargetUser($currentUser, $targetUser));
4965
-	}
4582
+        $this->defaultProvider->method('getSharesInFolder')
4583
+            ->with(
4584
+                $this->equalTo('user'),
4585
+                $this->equalTo($folder),
4586
+                $this->equalTo(false)
4587
+            )->willReturn([
4588
+                1 => [$share1],
4589
+                2 => [$share2],
4590
+            ]);
4591
+
4592
+        $extraProvider->method('getSharesInFolder')
4593
+            ->with(
4594
+                $this->equalTo('user'),
4595
+                $this->equalTo($folder),
4596
+                $this->equalTo(false)
4597
+            )->willReturn([
4598
+                2 => [$share3],
4599
+                3 => [$share4],
4600
+            ]);
4601
+
4602
+        $result = $manager->getSharesInFolder('user', $folder, false);
4603
+
4604
+        $expects = [
4605
+            1 => [$share1],
4606
+            2 => [$share2, $share3],
4607
+            3 => [$share4],
4608
+        ];
4609
+
4610
+        $this->assertSame($expects, $result);
4611
+    }
4612
+
4613
+    public function testGetSharesInFolderOwnerless(): void {
4614
+        $factory = new DummyFactory2($this->createMock(IServerContainer::class));
4615
+
4616
+        $manager = $this->createManager($factory);
4617
+
4618
+        $factory->setProvider($this->defaultProvider);
4619
+        $extraProvider = $this->createMock(IShareProviderSupportsAllSharesInFolder::class);
4620
+        $factory->setSecondProvider($extraProvider);
4621
+
4622
+        $share1 = $this->createMock(IShare::class);
4623
+        $share2 = $this->createMock(IShare::class);
4624
+
4625
+        $mount = $this->createMock(IShareOwnerlessMount::class);
4626
+
4627
+        $folder = $this->createMock(Folder::class);
4628
+        $folder
4629
+            ->method('getMountPoint')
4630
+            ->willReturn($mount);
4631
+
4632
+        $this->defaultProvider
4633
+            ->method('getAllSharesInFolder')
4634
+            ->with($folder)
4635
+            ->willReturn([1 => [$share1]]);
4636
+
4637
+        $extraProvider
4638
+            ->method('getAllSharesInFolder')
4639
+            ->with($folder)
4640
+            ->willReturn([1 => [$share2]]);
4641
+
4642
+        $this->assertSame([
4643
+            1 => [$share1, $share2],
4644
+        ], $manager->getSharesInFolder('user', $folder));
4645
+    }
4646
+
4647
+
4648
+    public function testGetAccessList(): void {
4649
+        $factory = new DummyFactory2($this->createMock(IServerContainer::class));
4650
+
4651
+        $manager = $this->createManager($factory);
4652
+
4653
+        $factory->setProvider($this->defaultProvider);
4654
+        $extraProvider = $this->createMock(IShareProvider::class);
4655
+        $factory->setSecondProvider($extraProvider);
4656
+
4657
+        $nodeOwner = $this->createMock(IUser::class);
4658
+        $nodeOwner->expects($this->once())
4659
+            ->method('getUID')
4660
+            ->willReturn('user1');
4661
+
4662
+        $node = $this->createMock(Node::class);
4663
+        $node->expects($this->once())
4664
+            ->method('getOwner')
4665
+            ->willReturn($nodeOwner);
4666
+        $node->method('getId')
4667
+            ->willReturn(42);
4668
+
4669
+        $userFolder = $this->createMock(Folder::class);
4670
+        $file = $this->createMock(File::class);
4671
+        $folder = $this->createMock(Folder::class);
4672
+
4673
+        $owner = $this->createMock(IUser::class);
4674
+        $owner->expects($this->once())
4675
+            ->method('getUID')
4676
+            ->willReturn('owner');
4677
+
4678
+        $file->method('getParent')
4679
+            ->willReturn($folder);
4680
+        $file->method('getPath')
4681
+            ->willReturn('/owner/files/folder/file');
4682
+        $file->method('getOwner')
4683
+            ->willReturn($owner);
4684
+        $file->method('getId')
4685
+            ->willReturn(23);
4686
+        $folder->method('getParent')
4687
+            ->willReturn($userFolder);
4688
+        $folder->method('getPath')
4689
+            ->willReturn('/owner/files/folder');
4690
+        $userFolder->method('getFirstNodeById')
4691
+            ->with($this->equalTo(42))
4692
+            ->willReturn($file);
4693
+        $userFolder->method('getPath')
4694
+            ->willReturn('/user1/files');
4695
+
4696
+        $this->userManager->method('userExists')
4697
+            ->with($this->equalTo('user1'))
4698
+            ->willReturn(true);
4699
+
4700
+        $this->defaultProvider->method('getAccessList')
4701
+            ->with(
4702
+                $this->equalTo([$file, $folder]),
4703
+                false
4704
+            )
4705
+            ->willReturn([
4706
+                'users' => [
4707
+                    'user1',
4708
+                    'user2',
4709
+                    'user3',
4710
+                    '123456',
4711
+                ],
4712
+                'public' => true,
4713
+            ]);
4714
+
4715
+        $extraProvider->method('getAccessList')
4716
+            ->with(
4717
+                $this->equalTo([$file, $folder]),
4718
+                false
4719
+            )
4720
+            ->willReturn([
4721
+                'users' => [
4722
+                    'user3',
4723
+                    'user4',
4724
+                    'user5',
4725
+                    '234567',
4726
+                ],
4727
+                'remote' => true,
4728
+            ]);
4729
+
4730
+        $this->rootFolder->method('getUserFolder')
4731
+            ->with($this->equalTo('user1'))
4732
+            ->willReturn($userFolder);
4733
+
4734
+        $expected = [
4735
+            'users' => ['owner', 'user1', 'user2', 'user3', '123456','user4', 'user5', '234567'],
4736
+            'remote' => true,
4737
+            'public' => true,
4738
+        ];
4739
+
4740
+        $result = $manager->getAccessList($node, true, false);
4741
+
4742
+        $this->assertSame($expected['public'], $result['public']);
4743
+        $this->assertSame($expected['remote'], $result['remote']);
4744
+        $this->assertSame($expected['users'], $result['users']);
4745
+    }
4746
+
4747
+    public function testGetAccessListWithCurrentAccess(): void {
4748
+        $factory = new DummyFactory2($this->createMock(IServerContainer::class));
4749
+
4750
+        $manager = $this->createManager($factory);
4751
+
4752
+        $factory->setProvider($this->defaultProvider);
4753
+        $extraProvider = $this->createMock(IShareProvider::class);
4754
+        $factory->setSecondProvider($extraProvider);
4755
+
4756
+        $nodeOwner = $this->createMock(IUser::class);
4757
+        $nodeOwner->expects($this->once())
4758
+            ->method('getUID')
4759
+            ->willReturn('user1');
4760
+
4761
+        $node = $this->createMock(Node::class);
4762
+        $node->expects($this->once())
4763
+            ->method('getOwner')
4764
+            ->willReturn($nodeOwner);
4765
+        $node->method('getId')
4766
+            ->willReturn(42);
4767
+
4768
+        $userFolder = $this->createMock(Folder::class);
4769
+        $file = $this->createMock(File::class);
4770
+
4771
+        $owner = $this->createMock(IUser::class);
4772
+        $owner->expects($this->once())
4773
+            ->method('getUID')
4774
+            ->willReturn('owner');
4775
+        $folder = $this->createMock(Folder::class);
4776
+
4777
+        $file->method('getParent')
4778
+            ->willReturn($folder);
4779
+        $file->method('getPath')
4780
+            ->willReturn('/owner/files/folder/file');
4781
+        $file->method('getOwner')
4782
+            ->willReturn($owner);
4783
+        $file->method('getId')
4784
+            ->willReturn(23);
4785
+        $folder->method('getParent')
4786
+            ->willReturn($userFolder);
4787
+        $folder->method('getPath')
4788
+            ->willReturn('/owner/files/folder');
4789
+        $userFolder->method('getFirstNodeById')
4790
+            ->with($this->equalTo(42))
4791
+            ->willReturn($file);
4792
+        $userFolder->method('getPath')
4793
+            ->willReturn('/user1/files');
4794
+
4795
+        $this->userManager->method('userExists')
4796
+            ->with($this->equalTo('user1'))
4797
+            ->willReturn(true);
4798
+
4799
+        $this->defaultProvider->method('getAccessList')
4800
+            ->with(
4801
+                $this->equalTo([$file, $folder]),
4802
+                true
4803
+            )
4804
+            ->willReturn([
4805
+                'users' => [
4806
+                    'user1' => [],
4807
+                    'user2' => [],
4808
+                    'user3' => [],
4809
+                    '123456' => [],
4810
+                ],
4811
+                'public' => true,
4812
+            ]);
4813
+
4814
+        $extraProvider->method('getAccessList')
4815
+            ->with(
4816
+                $this->equalTo([$file, $folder]),
4817
+                true
4818
+            )
4819
+            ->willReturn([
4820
+                'users' => [
4821
+                    'user3' => [],
4822
+                    'user4' => [],
4823
+                    'user5' => [],
4824
+                    '234567' => [],
4825
+                ],
4826
+                'remote' => [
4827
+                    'remote1',
4828
+                ],
4829
+            ]);
4830
+
4831
+        $this->rootFolder->method('getUserFolder')
4832
+            ->with($this->equalTo('user1'))
4833
+            ->willReturn($userFolder);
4834
+
4835
+        $expected = [
4836
+            'users' => [
4837
+                'owner' => [
4838
+                    'node_id' => 23,
4839
+                    'node_path' => '/folder/file'
4840
+                ]
4841
+                , 'user1' => [], 'user2' => [], 'user3' => [], '123456' => [], 'user4' => [], 'user5' => [], '234567' => []],
4842
+            'remote' => [
4843
+                'remote1',
4844
+            ],
4845
+            'public' => true,
4846
+        ];
4847
+
4848
+        $result = $manager->getAccessList($node, true, true);
4849
+
4850
+        $this->assertSame($expected['public'], $result['public']);
4851
+        $this->assertSame($expected['remote'], $result['remote']);
4852
+        $this->assertSame($expected['users'], $result['users']);
4853
+    }
4854
+
4855
+    public function testGetAllShares(): void {
4856
+        $factory = new DummyFactory2($this->createMock(IServerContainer::class));
4857
+
4858
+        $manager = $this->createManager($factory);
4859
+
4860
+        $factory->setProvider($this->defaultProvider);
4861
+        $extraProvider = $this->createMock(IShareProvider::class);
4862
+        $factory->setSecondProvider($extraProvider);
4863
+
4864
+        $share1 = $this->createMock(IShare::class);
4865
+        $share2 = $this->createMock(IShare::class);
4866
+        $share3 = $this->createMock(IShare::class);
4867
+        $share4 = $this->createMock(IShare::class);
4868
+
4869
+        $this->defaultProvider->method('getAllShares')
4870
+            ->willReturnCallback(function () use ($share1, $share2) {
4871
+                yield $share1;
4872
+                yield $share2;
4873
+            });
4874
+        $extraProvider->method('getAllShares')
4875
+            ->willReturnCallback(function () use ($share3, $share4) {
4876
+                yield $share3;
4877
+                yield $share4;
4878
+            });
4879
+
4880
+        // "yield from", used in "getAllShares()", does not reset the keys, so
4881
+        // "use_keys" has to be disabled to collect all the values while
4882
+        // ignoring the keys returned by the generator.
4883
+        $result = iterator_to_array($manager->getAllShares(), $use_keys = false);
4884
+
4885
+        $expects = [$share1, $share2, $share3, $share4];
4886
+
4887
+        $this->assertSame($expects, $result);
4888
+    }
4889
+
4890
+    public static function dataCurrentUserCanEnumerateTargetUser(): array {
4891
+        return [
4892
+            'Full match guest' => [true, true, false, false, false, false, false, true],
4893
+            'Full match user' => [false, true, false, false, false, false, false, true],
4894
+            'Enumeration off guest' => [true, false, false, false, false, false, false, false],
4895
+            'Enumeration off user' => [false, false, false, false, false, false, false, false],
4896
+            'Enumeration guest' => [true, false, true, false, false, false, false, true],
4897
+            'Enumeration user' => [false, false, true, false, false, false, false, true],
4898
+
4899
+            // Restricted enumerations guests never works
4900
+            'Guest phone' => [true, false, true, true, false, false, false, false],
4901
+            'Guest group' => [true, false, true, false, true, false, false, false],
4902
+            'Guest both' => [true, false, true, true, true, false, false, false],
4903
+
4904
+            // Restricted enumerations users
4905
+            'User phone but not known' => [false, false, true, true, false, false, false, false],
4906
+            'User phone known' => [false, false, true, true, false, true, false, true],
4907
+            'User group but no match' => [false, false, true, false, true, false, false, false],
4908
+            'User group with match' => [false, false, true, false, true, false, true, true],
4909
+        ];
4910
+    }
4911
+
4912
+    /**
4913
+     * @param bool $expected
4914
+     */
4915
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataCurrentUserCanEnumerateTargetUser')]
4916
+    public function testCurrentUserCanEnumerateTargetUser(bool $currentUserIsGuest, bool $allowEnumerationFullMatch, bool $allowEnumeration, bool $limitEnumerationToPhone, bool $limitEnumerationToGroups, bool $isKnownToUser, bool $haveCommonGroup, bool $expected): void {
4917
+        /** @var IManager|MockObject $manager */
4918
+        $manager = $this->createManagerMock()
4919
+            ->onlyMethods([
4920
+                'allowEnumerationFullMatch',
4921
+                'allowEnumeration',
4922
+                'limitEnumerationToPhone',
4923
+                'limitEnumerationToGroups',
4924
+            ])
4925
+            ->getMock();
4926
+
4927
+        $manager->method('allowEnumerationFullMatch')
4928
+            ->willReturn($allowEnumerationFullMatch);
4929
+        $manager->method('allowEnumeration')
4930
+            ->willReturn($allowEnumeration);
4931
+        $manager->method('limitEnumerationToPhone')
4932
+            ->willReturn($limitEnumerationToPhone);
4933
+        $manager->method('limitEnumerationToGroups')
4934
+            ->willReturn($limitEnumerationToGroups);
4935
+
4936
+        $this->knownUserService->method('isKnownToUser')
4937
+            ->with('current', 'target')
4938
+            ->willReturn($isKnownToUser);
4939
+
4940
+        $currentUser = null;
4941
+        if (!$currentUserIsGuest) {
4942
+            $currentUser = $this->createMock(IUser::class);
4943
+            $currentUser->method('getUID')
4944
+                ->willReturn('current');
4945
+        }
4946
+        $targetUser = $this->createMock(IUser::class);
4947
+        $targetUser->method('getUID')
4948
+            ->willReturn('target');
4949
+
4950
+        if ($haveCommonGroup) {
4951
+            $this->groupManager->method('getUserGroupIds')
4952
+                ->willReturnMap([
4953
+                    [$targetUser, ['gid1', 'gid2']],
4954
+                    [$currentUser, ['gid2', 'gid3']],
4955
+                ]);
4956
+        } else {
4957
+            $this->groupManager->method('getUserGroupIds')
4958
+                ->willReturnMap([
4959
+                    [$targetUser, ['gid1', 'gid2']],
4960
+                    [$currentUser, ['gid3', 'gid4']],
4961
+                ]);
4962
+        }
4963
+
4964
+        $this->assertSame($expected, $manager->currentUserCanEnumerateTargetUser($currentUser, $targetUser));
4965
+    }
4966 4966
 }
4967 4967
 
4968 4968
 class DummyFactory implements IProviderFactory {
4969
-	/** @var IShareProvider */
4970
-	protected $provider;
4971
-
4972
-	public function __construct(IServerContainer $serverContainer) {
4973
-	}
4974
-
4975
-	/**
4976
-	 * @param IShareProvider $provider
4977
-	 */
4978
-	public function setProvider($provider) {
4979
-		$this->provider = $provider;
4980
-	}
4981
-
4982
-	/**
4983
-	 * @param string $id
4984
-	 * @return IShareProvider
4985
-	 */
4986
-	public function getProvider($id) {
4987
-		return $this->provider;
4988
-	}
4989
-
4990
-	/**
4991
-	 * @param int $shareType
4992
-	 * @return IShareProvider
4993
-	 */
4994
-	public function getProviderForType($shareType) {
4995
-		return $this->provider;
4996
-	}
4997
-
4998
-	/**
4999
-	 * @return IShareProvider[]
5000
-	 */
5001
-	public function getAllProviders() {
5002
-		return [$this->provider];
5003
-	}
5004
-
5005
-	public function registerProvider(string $shareProvier): void {
5006
-	}
4969
+    /** @var IShareProvider */
4970
+    protected $provider;
4971
+
4972
+    public function __construct(IServerContainer $serverContainer) {
4973
+    }
4974
+
4975
+    /**
4976
+     * @param IShareProvider $provider
4977
+     */
4978
+    public function setProvider($provider) {
4979
+        $this->provider = $provider;
4980
+    }
4981
+
4982
+    /**
4983
+     * @param string $id
4984
+     * @return IShareProvider
4985
+     */
4986
+    public function getProvider($id) {
4987
+        return $this->provider;
4988
+    }
4989
+
4990
+    /**
4991
+     * @param int $shareType
4992
+     * @return IShareProvider
4993
+     */
4994
+    public function getProviderForType($shareType) {
4995
+        return $this->provider;
4996
+    }
4997
+
4998
+    /**
4999
+     * @return IShareProvider[]
5000
+     */
5001
+    public function getAllProviders() {
5002
+        return [$this->provider];
5003
+    }
5004
+
5005
+    public function registerProvider(string $shareProvier): void {
5006
+    }
5007 5007
 }
5008 5008
 
5009 5009
 class DummyFactory2 extends DummyFactory {
5010
-	/** @var IShareProvider */
5011
-	private $provider2;
5012
-
5013
-	/**
5014
-	 * @param IShareProvider $provider
5015
-	 */
5016
-	public function setSecondProvider($provider) {
5017
-		$this->provider2 = $provider;
5018
-	}
5019
-
5020
-	public function getAllProviders() {
5021
-		return [$this->provider, $this->provider2];
5022
-	}
5023
-
5024
-	public function registerProvider(string $shareProvier): void {
5025
-	}
5010
+    /** @var IShareProvider */
5011
+    private $provider2;
5012
+
5013
+    /**
5014
+     * @param IShareProvider $provider
5015
+     */
5016
+    public function setSecondProvider($provider) {
5017
+        $this->provider2 = $provider;
5018
+    }
5019
+
5020
+    public function getAllProviders() {
5021
+        return [$this->provider, $this->provider2];
5022
+    }
5023
+
5024
+    public function registerProvider(string $shareProvier): void {
5025
+    }
5026 5026
 }
Please login to merge, or discard this patch.
tests/lib/Share20/ShareByMailProviderTest.php 1 patch
Indentation   +259 added lines, -259 removed lines patch added patch discarded remove patch
@@ -38,263 +38,263 @@
 block discarded – undo
38 38
  */
39 39
 #[\PHPUnit\Framework\Attributes\Group('DB')]
40 40
 class ShareByMailProviderTest extends TestCase {
41
-	use EmailValidatorTrait;
42
-
43
-	/** @var IDBConnection */
44
-	protected $dbConn;
45
-
46
-	/** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */
47
-	protected $userManager;
48
-
49
-	/** @var IRootFolder | \PHPUnit\Framework\MockObject\MockObject */
50
-	protected $rootFolder;
51
-
52
-	/** @var ShareByMailProvider */
53
-	protected $provider;
54
-
55
-	/** @var \PHPUnit\Framework\MockObject\MockObject|IMailer */
56
-	protected $mailer;
57
-
58
-	/** @var \PHPUnit\Framework\MockObject\MockObject|IL10N */
59
-	protected $l10n;
60
-
61
-	/** @var \PHPUnit\Framework\MockObject\MockObject|Defaults */
62
-	protected $defaults;
63
-
64
-	/** @var \PHPUnit\Framework\MockObject\MockObject|IURLGenerator */
65
-	protected $urlGenerator;
66
-
67
-	/** @var IConfig|MockObject */
68
-	protected $config;
69
-
70
-	/** @var LoggerInterface|MockObject */
71
-	private $logger;
72
-
73
-	/** @var IHasher|MockObject */
74
-	private $hasher;
75
-
76
-	/** @var \OCP\Activity\IManager|MockObject */
77
-	private $activityManager;
78
-
79
-	/** @var IEventDispatcher|MockObject */
80
-	private $eventDispatcher;
81
-
82
-	/** @var \OCP\Share\IManager|MockObject */
83
-	private $shareManager;
84
-
85
-	/** @var ISecureRandom|MockObject */
86
-	private $secureRandom;
87
-
88
-	/** @var SettingsManager|MockObject */
89
-	private $settingsManager;
90
-
91
-	protected function setUp(): void {
92
-		$this->dbConn = Server::get(IDBConnection::class);
93
-		$this->userManager = $this->createMock(IUserManager::class);
94
-		$this->rootFolder = $this->createMock(IRootFolder::class);
95
-		$this->mailer = $this->createMock(IMailer::class);
96
-		$this->l10n = $this->createMock(IL10N::class);
97
-		$this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock();
98
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
99
-		$this->logger = $this->createMock(LoggerInterface::class);
100
-		$this->activityManager = $this->createMock(\OCP\Activity\IManager::class);
101
-		$this->settingsManager = $this->createMock(SettingsManager::class);
102
-		$this->hasher = $this->createMock(IHasher::class);
103
-		$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
104
-		$this->shareManager = $this->createMock(\OCP\Share\IManager::class);
105
-		$this->secureRandom = $this->createMock(ISecureRandom::class);
106
-		$this->config = $this->createMock(IConfig::class);
107
-
108
-		// Empty share table
109
-		$this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
110
-
111
-		$this->provider = new ShareByMailProvider(
112
-			$this->config,
113
-			$this->dbConn,
114
-			$this->secureRandom,
115
-			$this->userManager,
116
-			$this->rootFolder,
117
-			$this->l10n,
118
-			$this->logger,
119
-			$this->mailer,
120
-			$this->urlGenerator,
121
-			$this->activityManager,
122
-			$this->settingsManager,
123
-			$this->defaults,
124
-			$this->hasher,
125
-			$this->eventDispatcher,
126
-			$this->shareManager,
127
-			$this->getEmailValidatorWithStrictEmailCheck(),
128
-		);
129
-	}
130
-
131
-	protected function tearDown(): void {
132
-		$this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
133
-		$this->dbConn->getQueryBuilder()->delete('filecache')->runAcrossAllShards()->executeStatement();
134
-		$this->dbConn->getQueryBuilder()->delete('storages')->executeStatement();
135
-	}
136
-
137
-	/**
138
-	 * @param int $shareType
139
-	 * @param string $sharedWith
140
-	 * @param string $sharedBy
141
-	 * @param string $shareOwner
142
-	 * @param string $itemType
143
-	 * @param int $fileSource
144
-	 * @param string $fileTarget
145
-	 * @param int $permissions
146
-	 * @param $token
147
-	 * @param $expiration
148
-	 * @param $parent
149
-	 * @return int
150
-	 *
151
-	 * @throws \OCP\DB\Exception
152
-	 */
153
-	private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner,
154
-		$itemType, $fileSource, $fileTarget, $permissions, $token, $expiration,
155
-		$parent) {
156
-		$qb = $this->dbConn->getQueryBuilder();
157
-		$qb->insert('share');
158
-
159
-		if ($shareType) {
160
-			$qb->setValue('share_type', $qb->expr()->literal($shareType));
161
-		}
162
-		if ($sharedWith) {
163
-			$qb->setValue('share_with', $qb->expr()->literal($sharedWith));
164
-		}
165
-		if ($sharedBy) {
166
-			$qb->setValue('uid_initiator', $qb->expr()->literal($sharedBy));
167
-		}
168
-		if ($shareOwner) {
169
-			$qb->setValue('uid_owner', $qb->expr()->literal($shareOwner));
170
-		}
171
-		if ($itemType) {
172
-			$qb->setValue('item_type', $qb->expr()->literal($itemType));
173
-		}
174
-		if ($fileSource) {
175
-			$qb->setValue('file_source', $qb->expr()->literal($fileSource));
176
-		}
177
-		if ($fileTarget) {
178
-			$qb->setValue('file_target', $qb->expr()->literal($fileTarget));
179
-		}
180
-		if ($permissions) {
181
-			$qb->setValue('permissions', $qb->expr()->literal($permissions));
182
-		}
183
-		if ($token) {
184
-			$qb->setValue('token', $qb->expr()->literal($token));
185
-		}
186
-		if ($expiration) {
187
-			$qb->setValue('expiration', $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_DATETIME_MUTABLE));
188
-		}
189
-		if ($parent) {
190
-			$qb->setValue('parent', $qb->expr()->literal($parent));
191
-		}
192
-
193
-		$this->assertEquals(1, $qb->executeStatement());
194
-		return $qb->getLastInsertId();
195
-	}
196
-
197
-	public function testGetSharesByWithResharesAndNoNode(): void {
198
-		$this->addShareToDB(
199
-			IShare::TYPE_EMAIL,
200
-			'[email protected]',
201
-			'user1',
202
-			'user1',
203
-			'folder',
204
-			42,
205
-			null,
206
-			17,
207
-			'foobar',
208
-			null,
209
-			null,
210
-		);
211
-		$this->addShareToDB(
212
-			IShare::TYPE_EMAIL,
213
-			'[email protected]',
214
-			'user2',
215
-			'user2',
216
-			'folder',
217
-			42,
218
-			null,
219
-			17,
220
-			'barfoo',
221
-			null,
222
-			null,
223
-		);
224
-
225
-		// Return own shares only if not asked for a specific node
226
-		/** @var IShare[] $actual */
227
-		$actual = $this->provider->getSharesBy(
228
-			'user1',
229
-			IShare::TYPE_EMAIL,
230
-			null,
231
-			true,
232
-			-1,
233
-			0,
234
-		);
235
-
236
-		$this->assertCount(1, $actual);
237
-
238
-		$this->assertEquals(IShare::TYPE_EMAIL, $actual[0]->getShareType());
239
-		$this->assertEquals('user1', $actual[0]->getSharedBy());
240
-		$this->assertEquals('user1', $actual[0]->getShareOwner());
241
-		$this->assertEquals('[email protected]', $actual[0]->getSharedWith());
242
-	}
243
-
244
-	public function testGetSharesByWithResharesAndNode(): void {
245
-		$this->addShareToDB(
246
-			IShare::TYPE_EMAIL,
247
-			'[email protected]',
248
-			'user1',
249
-			'user1',
250
-			'folder',
251
-			42,
252
-			null,
253
-			17,
254
-			'foobar',
255
-			null,
256
-			null,
257
-		);
258
-		$this->addShareToDB(
259
-			IShare::TYPE_EMAIL,
260
-			'[email protected]',
261
-			'user2',
262
-			'user2',
263
-			'folder',
264
-			42,
265
-			null,
266
-			17,
267
-			'barfoo',
268
-			null,
269
-			null,
270
-		);
271
-
272
-		$node = $this->createMock(Node::class);
273
-		$node->expects($this->once())
274
-			->method('getId')
275
-			->willReturn(42);
276
-
277
-		// Return all shares if asked for specific node
278
-		/** @var IShare[] $actual */
279
-		$actual = $this->provider->getSharesBy(
280
-			'user1',
281
-			IShare::TYPE_EMAIL,
282
-			$node,
283
-			true,
284
-			-1,
285
-			0,
286
-		);
287
-
288
-		$this->assertCount(2, $actual);
289
-
290
-		$this->assertEquals(IShare::TYPE_EMAIL, $actual[0]->getShareType());
291
-		$this->assertEquals('user1', $actual[0]->getSharedBy());
292
-		$this->assertEquals('user1', $actual[0]->getShareOwner());
293
-		$this->assertEquals('[email protected]', $actual[0]->getSharedWith());
294
-
295
-		$this->assertEquals(IShare::TYPE_EMAIL, $actual[1]->getShareType());
296
-		$this->assertEquals('user2', $actual[1]->getSharedBy());
297
-		$this->assertEquals('user2', $actual[1]->getShareOwner());
298
-		$this->assertEquals('[email protected]', $actual[1]->getSharedWith());
299
-	}
41
+    use EmailValidatorTrait;
42
+
43
+    /** @var IDBConnection */
44
+    protected $dbConn;
45
+
46
+    /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */
47
+    protected $userManager;
48
+
49
+    /** @var IRootFolder | \PHPUnit\Framework\MockObject\MockObject */
50
+    protected $rootFolder;
51
+
52
+    /** @var ShareByMailProvider */
53
+    protected $provider;
54
+
55
+    /** @var \PHPUnit\Framework\MockObject\MockObject|IMailer */
56
+    protected $mailer;
57
+
58
+    /** @var \PHPUnit\Framework\MockObject\MockObject|IL10N */
59
+    protected $l10n;
60
+
61
+    /** @var \PHPUnit\Framework\MockObject\MockObject|Defaults */
62
+    protected $defaults;
63
+
64
+    /** @var \PHPUnit\Framework\MockObject\MockObject|IURLGenerator */
65
+    protected $urlGenerator;
66
+
67
+    /** @var IConfig|MockObject */
68
+    protected $config;
69
+
70
+    /** @var LoggerInterface|MockObject */
71
+    private $logger;
72
+
73
+    /** @var IHasher|MockObject */
74
+    private $hasher;
75
+
76
+    /** @var \OCP\Activity\IManager|MockObject */
77
+    private $activityManager;
78
+
79
+    /** @var IEventDispatcher|MockObject */
80
+    private $eventDispatcher;
81
+
82
+    /** @var \OCP\Share\IManager|MockObject */
83
+    private $shareManager;
84
+
85
+    /** @var ISecureRandom|MockObject */
86
+    private $secureRandom;
87
+
88
+    /** @var SettingsManager|MockObject */
89
+    private $settingsManager;
90
+
91
+    protected function setUp(): void {
92
+        $this->dbConn = Server::get(IDBConnection::class);
93
+        $this->userManager = $this->createMock(IUserManager::class);
94
+        $this->rootFolder = $this->createMock(IRootFolder::class);
95
+        $this->mailer = $this->createMock(IMailer::class);
96
+        $this->l10n = $this->createMock(IL10N::class);
97
+        $this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock();
98
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
99
+        $this->logger = $this->createMock(LoggerInterface::class);
100
+        $this->activityManager = $this->createMock(\OCP\Activity\IManager::class);
101
+        $this->settingsManager = $this->createMock(SettingsManager::class);
102
+        $this->hasher = $this->createMock(IHasher::class);
103
+        $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
104
+        $this->shareManager = $this->createMock(\OCP\Share\IManager::class);
105
+        $this->secureRandom = $this->createMock(ISecureRandom::class);
106
+        $this->config = $this->createMock(IConfig::class);
107
+
108
+        // Empty share table
109
+        $this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
110
+
111
+        $this->provider = new ShareByMailProvider(
112
+            $this->config,
113
+            $this->dbConn,
114
+            $this->secureRandom,
115
+            $this->userManager,
116
+            $this->rootFolder,
117
+            $this->l10n,
118
+            $this->logger,
119
+            $this->mailer,
120
+            $this->urlGenerator,
121
+            $this->activityManager,
122
+            $this->settingsManager,
123
+            $this->defaults,
124
+            $this->hasher,
125
+            $this->eventDispatcher,
126
+            $this->shareManager,
127
+            $this->getEmailValidatorWithStrictEmailCheck(),
128
+        );
129
+    }
130
+
131
+    protected function tearDown(): void {
132
+        $this->dbConn->getQueryBuilder()->delete('share')->executeStatement();
133
+        $this->dbConn->getQueryBuilder()->delete('filecache')->runAcrossAllShards()->executeStatement();
134
+        $this->dbConn->getQueryBuilder()->delete('storages')->executeStatement();
135
+    }
136
+
137
+    /**
138
+     * @param int $shareType
139
+     * @param string $sharedWith
140
+     * @param string $sharedBy
141
+     * @param string $shareOwner
142
+     * @param string $itemType
143
+     * @param int $fileSource
144
+     * @param string $fileTarget
145
+     * @param int $permissions
146
+     * @param $token
147
+     * @param $expiration
148
+     * @param $parent
149
+     * @return int
150
+     *
151
+     * @throws \OCP\DB\Exception
152
+     */
153
+    private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner,
154
+        $itemType, $fileSource, $fileTarget, $permissions, $token, $expiration,
155
+        $parent) {
156
+        $qb = $this->dbConn->getQueryBuilder();
157
+        $qb->insert('share');
158
+
159
+        if ($shareType) {
160
+            $qb->setValue('share_type', $qb->expr()->literal($shareType));
161
+        }
162
+        if ($sharedWith) {
163
+            $qb->setValue('share_with', $qb->expr()->literal($sharedWith));
164
+        }
165
+        if ($sharedBy) {
166
+            $qb->setValue('uid_initiator', $qb->expr()->literal($sharedBy));
167
+        }
168
+        if ($shareOwner) {
169
+            $qb->setValue('uid_owner', $qb->expr()->literal($shareOwner));
170
+        }
171
+        if ($itemType) {
172
+            $qb->setValue('item_type', $qb->expr()->literal($itemType));
173
+        }
174
+        if ($fileSource) {
175
+            $qb->setValue('file_source', $qb->expr()->literal($fileSource));
176
+        }
177
+        if ($fileTarget) {
178
+            $qb->setValue('file_target', $qb->expr()->literal($fileTarget));
179
+        }
180
+        if ($permissions) {
181
+            $qb->setValue('permissions', $qb->expr()->literal($permissions));
182
+        }
183
+        if ($token) {
184
+            $qb->setValue('token', $qb->expr()->literal($token));
185
+        }
186
+        if ($expiration) {
187
+            $qb->setValue('expiration', $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_DATETIME_MUTABLE));
188
+        }
189
+        if ($parent) {
190
+            $qb->setValue('parent', $qb->expr()->literal($parent));
191
+        }
192
+
193
+        $this->assertEquals(1, $qb->executeStatement());
194
+        return $qb->getLastInsertId();
195
+    }
196
+
197
+    public function testGetSharesByWithResharesAndNoNode(): void {
198
+        $this->addShareToDB(
199
+            IShare::TYPE_EMAIL,
200
+            '[email protected]',
201
+            'user1',
202
+            'user1',
203
+            'folder',
204
+            42,
205
+            null,
206
+            17,
207
+            'foobar',
208
+            null,
209
+            null,
210
+        );
211
+        $this->addShareToDB(
212
+            IShare::TYPE_EMAIL,
213
+            '[email protected]',
214
+            'user2',
215
+            'user2',
216
+            'folder',
217
+            42,
218
+            null,
219
+            17,
220
+            'barfoo',
221
+            null,
222
+            null,
223
+        );
224
+
225
+        // Return own shares only if not asked for a specific node
226
+        /** @var IShare[] $actual */
227
+        $actual = $this->provider->getSharesBy(
228
+            'user1',
229
+            IShare::TYPE_EMAIL,
230
+            null,
231
+            true,
232
+            -1,
233
+            0,
234
+        );
235
+
236
+        $this->assertCount(1, $actual);
237
+
238
+        $this->assertEquals(IShare::TYPE_EMAIL, $actual[0]->getShareType());
239
+        $this->assertEquals('user1', $actual[0]->getSharedBy());
240
+        $this->assertEquals('user1', $actual[0]->getShareOwner());
241
+        $this->assertEquals('[email protected]', $actual[0]->getSharedWith());
242
+    }
243
+
244
+    public function testGetSharesByWithResharesAndNode(): void {
245
+        $this->addShareToDB(
246
+            IShare::TYPE_EMAIL,
247
+            '[email protected]',
248
+            'user1',
249
+            'user1',
250
+            'folder',
251
+            42,
252
+            null,
253
+            17,
254
+            'foobar',
255
+            null,
256
+            null,
257
+        );
258
+        $this->addShareToDB(
259
+            IShare::TYPE_EMAIL,
260
+            '[email protected]',
261
+            'user2',
262
+            'user2',
263
+            'folder',
264
+            42,
265
+            null,
266
+            17,
267
+            'barfoo',
268
+            null,
269
+            null,
270
+        );
271
+
272
+        $node = $this->createMock(Node::class);
273
+        $node->expects($this->once())
274
+            ->method('getId')
275
+            ->willReturn(42);
276
+
277
+        // Return all shares if asked for specific node
278
+        /** @var IShare[] $actual */
279
+        $actual = $this->provider->getSharesBy(
280
+            'user1',
281
+            IShare::TYPE_EMAIL,
282
+            $node,
283
+            true,
284
+            -1,
285
+            0,
286
+        );
287
+
288
+        $this->assertCount(2, $actual);
289
+
290
+        $this->assertEquals(IShare::TYPE_EMAIL, $actual[0]->getShareType());
291
+        $this->assertEquals('user1', $actual[0]->getSharedBy());
292
+        $this->assertEquals('user1', $actual[0]->getShareOwner());
293
+        $this->assertEquals('[email protected]', $actual[0]->getSharedWith());
294
+
295
+        $this->assertEquals(IShare::TYPE_EMAIL, $actual[1]->getShareType());
296
+        $this->assertEquals('user2', $actual[1]->getSharedBy());
297
+        $this->assertEquals('user2', $actual[1]->getShareOwner());
298
+        $this->assertEquals('[email protected]', $actual[1]->getSharedWith());
299
+    }
300 300
 }
Please login to merge, or discard this patch.
tests/lib/Federation/CloudIdTest.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -17,31 +17,31 @@
 block discarded – undo
17 17
 
18 18
 #[\PHPUnit\Framework\Attributes\Group('DB')]
19 19
 class CloudIdTest extends TestCase {
20
-	protected CloudIdManager&MockObject $cloudIdManager;
21
-
22
-	protected function setUp(): void {
23
-		parent::setUp();
24
-
25
-		$this->cloudIdManager = $this->createMock(CloudIdManager::class);
26
-		$this->overwriteService(ICloudIdManager::class, $this->cloudIdManager);
27
-	}
28
-
29
-	public static function dataGetDisplayCloudId(): array {
30
-		return [
31
-			['[email protected]', 'test', 'example.com', '[email protected]'],
32
-			['test@http://example.com', 'test', 'http://example.com', '[email protected]'],
33
-			['test@https://example.com', 'test', 'https://example.com', '[email protected]'],
34
-			['test@https://example.com', 'test', 'https://example.com', 'Beloved [email protected]', 'Beloved Amy'],
35
-		];
36
-	}
37
-
38
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataGetDisplayCloudId')]
39
-	public function testGetDisplayCloudId(string $id, string $user, string $remote, string $display, ?string $addressbookName = null): void {
40
-		$this->cloudIdManager->expects($this->once())
41
-			->method('getDisplayNameFromContact')
42
-			->willReturn($addressbookName);
43
-
44
-		$cloudId = new CloudId($id, $user, $remote);
45
-		$this->assertEquals($display, $cloudId->getDisplayId());
46
-	}
20
+    protected CloudIdManager&MockObject $cloudIdManager;
21
+
22
+    protected function setUp(): void {
23
+        parent::setUp();
24
+
25
+        $this->cloudIdManager = $this->createMock(CloudIdManager::class);
26
+        $this->overwriteService(ICloudIdManager::class, $this->cloudIdManager);
27
+    }
28
+
29
+    public static function dataGetDisplayCloudId(): array {
30
+        return [
31
+            ['[email protected]', 'test', 'example.com', '[email protected]'],
32
+            ['test@http://example.com', 'test', 'http://example.com', '[email protected]'],
33
+            ['test@https://example.com', 'test', 'https://example.com', '[email protected]'],
34
+            ['test@https://example.com', 'test', 'https://example.com', 'Beloved [email protected]', 'Beloved Amy'],
35
+        ];
36
+    }
37
+
38
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataGetDisplayCloudId')]
39
+    public function testGetDisplayCloudId(string $id, string $user, string $remote, string $display, ?string $addressbookName = null): void {
40
+        $this->cloudIdManager->expects($this->once())
41
+            ->method('getDisplayNameFromContact')
42
+            ->willReturn($addressbookName);
43
+
44
+        $cloudId = new CloudId($id, $user, $remote);
45
+        $this->assertEquals($display, $cloudId->getDisplayId());
46
+    }
47 47
 }
Please login to merge, or discard this patch.