Issues (4868)

admin/tests/PreferencesCommandTest.php (2 issues)

1
<?php
2
3
/**
4
 * Tests for edit preferences command
5
 *
6
 * @link http://www.egroupware.org
7
 * @author Nathan Gray
8
 * @copyright (c) 2018  Nathan Gray
9
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
10
 */
11
12
// test base providing common stuff
13
require_once __DIR__.'/CommandBase.php';
14
15
use EGroupware\Api;
16
17
class PreferencesCommandTest extends CommandBase
18
{
19
20
	// Use the same app for everything
21
	const APP = 'common';
22
23
	// If we add a preference, make sure we can delete it for clean up
24
	protected $preference_name = 'test_preference';
25
26
	protected function setUp() : void
27
	{
28
		Api\Cache::unsetInstance(Api\Preferences::class, 'forced');
29
		Api\Cache::unsetInstance(Api\Preferences::class, 'default');
30
		Api\Cache::unsetInstance(Api\Preferences::class, $GLOBALS['egw_info']['user']['account_id']);
31
	}
32
	protected function tearDown() : void
33
	{
34
		if($this->preference_name)
35
		{
36
			Api\Preferences::delete_preference(static::APP, $this->preference_name, 'user');
37
			Api\Preferences::delete_preference(static::APP, $this->preference_name, 'default');
38
			Api\Preferences::delete_preference(static::APP, $this->preference_name, 'forced');
39
		}
40
41
		Api\Cache::unsetInstance(Api\Preferences::class, 'forced');
42
		Api\Cache::unsetInstance(Api\Preferences::class, 'default');
43
		Api\Cache::unsetInstance(Api\Preferences::class, $GLOBALS['egw_info']['user']['account_id']);
44
		parent::tearDown();
45
	}
46
47
	/**
48
	 * Test that adding a preference works
49
	 *
50
	 * @dataProvider typeDataProvider
51
	 */
52
	public function testAddPreference($type)
53
	{
54
		// Set up
55
		$log_count = $this->get_log_count();
56
		$account = $type == 'group' ? $GLOBALS['egw']->accounts->name2id('Default') : $GLOBALS['egw_info']['user']['account_id'];
57
		$pre_pref = new Api\Preferences($GLOBALS['egw_info']['user']['account_id']);
58
		$pre = $pre_pref->read(static::APP);
0 ignored issues
show
The call to EGroupware\Api\Preferences::read() has too many arguments starting with static::APP. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
		/** @scrutinizer ignore-call */ 
59
  $pre = $pre_pref->read(static::APP);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
59
		$this->assertArrayNotHasKey($this->preference_name, $pre);
60
61
		$set = array($this->preference_name => 'Yes');
62
63
		// Execute
64
		$command = new admin_cmd_edit_preferences($account, $type, static::APP, $set);
65
		$command->comment = 'Needed for unit test ' . $this->getName() . " with type $type";
66
		$command->run();
67
68
		// Check
69
		$post_pref = new Api\Preferences($GLOBALS['egw_info']['user']['account_id']);
70
		$post = $post_pref->read_repository(false);
71
		// At user level
72
		$this->assertArrayHasKey($this->preference_name, $post[static::APP]);
73
		$this->assertEquals($set[$this->preference_name], $post[static::APP][$this->preference_name]);
74
		// At type level
75
		// Get type as an array since direct sub-access doesn't work in 5.6
76
		$post_app = $post_pref->$type;
77
		$this->assertArrayHasKey($this->preference_name, $post_app[static::APP],
78
				"$type preferences does not have {$this->preference_name}");
79
		$this->assertEquals($set[$this->preference_name], $post_app[static::APP][$this->preference_name]);
80
81
		$this->assertGreaterThan($log_count, $this->get_log_count(), "Command ($command) did not log");
82
	}
83
84
	/**
85
	 * Try to change an existing preference
86
	 *
87
	 * We check changing the various combinations with a default set.
88
	 * All should give a change.
89
	 *
90
	 * @dataProvider typeDataProvider
91
	 */
92
	public function testChangeWithDefault($type)
93
	{
94
		// Set up
95
		$log_count = $this->get_log_count();
96
		$account = $GLOBALS['egw_info']['user']['account_id'];
97
98
		$set = array($this->preference_name => 'Changed');
99
		$old = array($this->preference_name => $type . ' original value');
100
101
		$prefs = new Api\Preferences('default');
102
		$prefs->read_repository(false);
103
		$prefs->add(static::APP, $this->preference_name, 'default original value','default');
104
		$prefs->save_repository('default');
105
106
		$prefs = new Api\Preferences(in_array($type, array('default', 'forced')) ? $type : $account);
107
		$prefs->read_repository(false);
108
		$prefs->add(static::APP, $this->preference_name, $old[$this->preference_name], $type);
109
		$prefs->save_repository($type);
110
111
		// Execute
112
		$command = new admin_cmd_edit_preferences($account, $type, static::APP, $set, $old);
113
		$command->comment = 'Needed for unit test ' . $this->getName();
114
		$command->run();
115
116
		// Check
117
		$post_pref = new Api\Preferences($account);
118
		$post = $post_pref->read_repository(false);
119
120
		// At user level
121
		$this->assertArrayHasKey($this->preference_name, $post[static::APP]);
122
		$this->assertEquals($set[$this->preference_name], $post[static::APP][$this->preference_name]);
123
124
		// At type level
125
		// Get type as an array since direct sub-access doesn't work in 5.6
126
		$post_app = $post_pref->$type;
127
		$this->assertArrayHasKey($this->preference_name, $post_app[static::APP],
128
				"$type preferences does not have {$this->preference_name}");
129
		$this->assertEquals($set[$this->preference_name], $post_app[static::APP][$this->preference_name]);
130
131
		$this->assertGreaterThan($log_count, $this->get_log_count(), "Command ($command) did not log");
132
	}
133
134
	/**
135
	 * Try to change an existing preference
136
	 *
137
	 * We check changing the various combinations with a default set.
138
	 * Only forced should give a change.
139
	 *
140
	 * @dataProvider typeDataProvider
141
	 */
142
	public function testChangeWithForced($type)
143
	{
144
		// Set up
145
		$log_count = $this->get_log_count();
146
		$account = $GLOBALS['egw_info']['user']['account_id'];
147
148
		$set = array($this->preference_name => 'Changed '. $type);
149
		$old = array($this->preference_name => $type . ' original value');
150
151
		$prefs = new Api\Preferences('forced');
152
		$prefs->read_repository(false);
153
		$prefs->add(static::APP, $this->preference_name, 'forced original value','forced');
154
		$prefs->save_repository(false, 'forced');
155
156
		$prefs = new Api\Preferences(in_array($type, array('default', 'forced')) ? $type : $account);
157
		$prefs->read_repository(false);
158
		$prefs->add(static::APP, $this->preference_name, $old[$this->preference_name], $type);
159
		$prefs->save_repository(false, $type);
160
161
		// Execute
162
		$command = new admin_cmd_edit_preferences($account, $type, static::APP, $set, $old);
163
		$command->comment = 'Needed for unit test ' . $this->getName();
164
		$command->run();
165
166
		// Check
167
		$post_pref = new Api\Preferences($account);
168
		$post = $post_pref->read_repository(false);
169
170
		// At user level
171
		$this->assertArrayHasKey($this->preference_name, $post[static::APP]);
172
		$this->assertEquals($type != 'forced' ? 'forced original value' : $set[$this->preference_name], $post[static::APP][$this->preference_name],
173
				"$type preference overrode forced preference"
174
		);
175
176
		// At type level
177
		// Get type as an array since direct sub-access doesn't work in 5.6
178
		$post_app = $post_pref->$type;
179
		$this->assertArrayHasKey($this->preference_name, $post_app[static::APP],
180
				"$type preferences does not have {$this->preference_name}");
181
		$this->assertEquals($set[$this->preference_name], $post_app[static::APP][$this->preference_name]);
182
183
		$this->assertGreaterThan($log_count, $this->get_log_count(), "Command ($command) did not log");
184
	}
185
186
	/**
187
	 * Try to change an existing preference
188
	 *
189
	 * We check changing the various combinations, some of which should change
190
	 *
191
	 * @dataProvider typeChangeDataProvider
192
	 */
193
	public function testChange($type, $check, $change)
194
	{
195
		// Set up
196
		$log_count = $this->get_log_count();
197
		$account = $GLOBALS['egw_info']['user']['account_id'];
198
199
200
		$set = array($this->preference_name => $type . ' changed');
201
		$old = array($this->preference_name => $type . ' original value');
202
		$check_original = $check . ' original value';
203
		//echo "\n".__METHOD__ . "($type, $check, $change) Change $type but $check should " . ($change ? '' : 'not ') . "change ( " . ($change ? $set[$this->preference_name] : $check_original).")\n";
204
205
		$prefs = new Api\Preferences(in_array($type, array('default', 'forced')) ? $type : $account);
206
		$prefs->read_repository(false);
207
		$prefs->add(static::APP, $this->preference_name, $old[$this->preference_name], $type);
208
		$prefs->save_repository(False, $type);
209
210
		$prefs = new Api\Preferences(in_array($check, array('default', 'forced')) ? $check : $account);
211
		$prefs->read_repository(false);
212
		$prefs->add(static::APP, $this->preference_name, $check_original, $check);
213
		$prefs->save_repository(False, $check);
214
215
		// Execute
216
		$command = new admin_cmd_edit_preferences($account, $type, static::APP, $set, $old);
217
		$command->comment = 'Needed for unit test ' . $this->getName();
218
		$command->run();
219
220
		// Check
221
		$post_pref = new Api\Preferences($account);
222
		$post = $post_pref->read_repository(false);
223
224
		// At type level - should always be what we set
225
		// Get type as an array since direct sub-access doesn't work in 5.6
226
		$post_app = $post_pref->$type;
227
		$this->assertArrayHasKey($this->preference_name, $post_app[static::APP],
228
				"$type preferences does not have {$this->preference_name}");
229
		$this->assertEquals($set[$this->preference_name], $post_app[static::APP][$this->preference_name]);
230
231
		// At user level - depends on type priority
232
		$this->assertArrayHasKey($this->preference_name, $post[static::APP]);
233
		$this->assertEquals($change ? $set[$this->preference_name] : $check_original, $post[static::APP][$this->preference_name]);
234
235
236
		$this->assertGreaterThan($log_count, $this->get_log_count(), "Command ($command) did not log");
237
	}
238
239
	/**
240
	 * Try to delete an existing preference
241
	 *
242
	 * We check the various combinations, such as deleting a default when the user
243
	 * has a value.
244
	 *
245
	 * @dataProvider typeChangeDataProvider
246
	 */
247
	public function testDeletePreference($type, $check, $override)
248
	{
249
		// Set up
250
		$log_count = $this->get_log_count();
251
		$account = $type == 'group' ? $GLOBALS['egw']->accounts->name2id('Default') : $GLOBALS['egw_info']['user']['account_id'];
252
253
		$set = array($this->config_name => null);
0 ignored issues
show
Bug Best Practice introduced by
The property config_name does not exist on PreferencesCommandTest. Did you maybe forget to declare it?
Loading history...
254
		$old = array($this->config_name => 'It will log whatever');
255
256
		$prefs = new Api\Preferences(in_array($type, array('default', 'forced')) ? $type : $account);
257
		$prefs->add(static::APP, $this->config_name, $old[$this->config_name], in_array($type, array('default', 'forced')) ? $type : 'user');
258
		$prefs->save_repository(false, $type);
259
260
261
		// Execute
262
		$command = new admin_cmd_edit_preferences($account, $type, static::APP, $set, $old);
263
		$command->comment = 'Needed for unit test ' . $this->getName();
264
		$command->run();
265
266
		// Check
267
		$account = $check == 'group' ? $GLOBALS['egw']->accounts->name2id('Default') : $GLOBALS['egw_info']['user']['account_id'];
268
		$post_pref = new Api\Preferences($account);
269
		$post = $post_pref->read_repository();
270
271
		// At user level
272
		$this->assertEquals($override ? $set[$this->preference_name] : $old[$this->preference_name], $post[static::APP][$this->preference_name]);
273
274
		// At type level
275
		// Get type as an array since direct sub-access doesn't work in 5.6
276
		$post_app = $post_pref->$check;
277
		$this->assertNull($post_app[static::APP][$this->preference_name]);
278
279
		$this->assertGreaterThan($log_count, $this->get_log_count(), "Command ($command) did not log");
280
	}
281
282
283
	/**
284
	 * Give a list of preference levels (types) so we can check them all
285
	 * They are in priority order.
286
	 */
287
	public function typeDataProvider() {
288
		return array(
289
			Array('default'),
290
			Array('user'),
291
			//Array('group'), Not really supported yet
292
			Array('forced')
293
		);
294
	}
295
296
	/**
297
	 * Get a list of preference levels and if they should be allowed to change
298
	 * each other
299
	 */
300
	public function typeChangeDataProvider() {
301
		$levels = array(
302
			// Change and this should/should not change
303
			Array('default', 'user',   false),
304
			Array('default', 'forced', false),
305
			Array('user',    'default', true),
306
			Array('user',    'forced', false),
307
			Array('forced',  'user',    true),
308
			Array('forced',  'default', true),
309
		);
310
311
312
		return $levels;
313
	}
314
}