PluginProbe
Groups – Memberships and Access Control / 1.11.0
Groups – Memberships and Access Control v1.11.0
4.7.1 4.7.0 4.6.0 4.5.0 4.4.0 4.3.0 trunk 1.0.0-beta-1 1.0.0-beta-2 1.0.0-beta-3 1.0.0-beta-3b 1.0.0-beta-3c 1.0.0-beta-3d 1.1.4 1.1.5 1.10.0 1.10.1 1.10.2 1.10.3 1.11.0 1.11.1 1.11.2 1.11.3 1.12.0 1.13.0 All 131 releases
groups / lib / test / groups-tests.php

groups-tests.php in Groups – Memberships and Access Control 1.11.0, at lib/test/groups-tests.php

424 lines 16.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * groups-tests.php
4 *
5 * Copyright (c) "kento" Karim Rahimpur www.itthinx.com
6 *
7 * This code is released under the GNU General Public License.
8 * See COPYRIGHT.txt and LICENSE.txt.
9 *
10 * This code is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * This header and all notices must be kept intact.
16 *
17 * @author Karim Rahimpur
18 * @package groups
19 * @since groups 1.0.0
20 */
21 // bootstrap WordPress
22 if ( !defined( 'ABSPATH' ) ) {
23 $wp_load = 'wp-load.php';
24 $max_depth = 100; // prevent death by depth
25 while ( !file_exists( $wp_load ) && ( $max_depth > 0 ) ) {
26 $wp_load = '../' . $wp_load;
27 $max_depth--;
28 }
29 if ( file_exists( $wp_load ) ) {
30 require_once $wp_load;
31 }
32 }
33 if ( defined( 'ABSPATH' ) ) {
34
35 function groups_tests() {
36
37 assert_options( ASSERT_ACTIVE, true );
38 assert_options( ASSERT_WARNING, true );
39 assert_options( ASSERT_BAIL, false );
40
41 //
42 // PART 1 : create test data
43 //
44
45 // *** groups ***
46
47 // create valid test groups
48 //
49 // Fruits [dance] {foo}
50 // / \
51 // Sweet {dol} Sour [sing]
52 // | |
53 // Banana {baz} Lemon {bar}
54 //
55 // All groups can dance.
56 // Only Sour and Lemon can sing.
57 $fruits_group_id = Groups_Group::create( array( 'name' => 'Fruits' ) );
58 assert( '$fruits_group_id !== false' );
59 $sweet_group_id = Groups_Group::create( array( 'name' => 'Sweet', 'parent_id' => $fruits_group_id ) );
60 assert( '$sweet_group_id !== false' );
61 $sour_group_id = Groups_Group::create( array( 'name' => 'Sour', 'parent_id' => $fruits_group_id ) );
62 assert( '$sour_group_id !== false' );
63 $lemon_group_id = Groups_Group::create( array( 'name' => 'Lemon', 'parent_id' => $sour_group_id ) );
64 assert( '$lemon_group_id !== false' );
65 $banana_group_id = Groups_Group::create( array( 'name' => 'Banana', 'parent_id' => $sweet_group_id ) );
66 assert( '$banana_group_id !== false' );
67
68 // fail to create group with missing name
69 $bogus_group_id = Groups_Group::create( array( ) );
70 assert( '$bogus_group_id === false; /* empty name */' );
71
72 // fail to create group with wrong parent_id
73 $bogus_group_id = Groups_Group::create( array( 'name' => 'bogus', 'parent_id' => -1 ) );
74 assert( '$bogus_group_id === false; /* wrong parent_id */' );
75
76 // *** capabilities ***
77 $sing_capability_id = Groups_Capability::create( array( 'capability' => 'sing' ) );
78 assert( '$sing_capability_id !== false' );
79
80 $dance_capability_id = Groups_Capability::create( array( 'capability' => 'dance' ) );
81 assert( '$dance_capability_id !== false' );
82
83 $clap_capability_id = Groups_Capability::create( array( 'capability' => 'clap' ) );
84 assert( '$clap_capability_id !== false' );
85
86 // read capability by id
87 assert( 'Groups_Capability::read( $sing_capability_id )' );
88
89 // read capability by unique label
90 assert( 'Groups_Capability::read_by_capability( "dance" )' );
91
92
93 // *** users ***
94
95 // create test users
96 $fooname = 'foo' . rand(0, 100);
97 $foo_user_id = wp_create_user( $fooname, 'foo', $fooname . '@example.com' );
98 assert( '$foo_user_id instanceof WP_Error === false');
99
100 $barname = 'bar' . rand(0, 100);
101 $bar_user_id = wp_create_user( $barname, 'bar', $barname . '@example.com' );
102 assert( '$bar_user_id instanceof WP_Error === false');
103
104 // this user is used to test the automatic resolution of its relationship
105 // with the banana group when the group is deleted
106 // it's also used to test automatic resolution of its "clap" capability
107 // after that capability has been deleted
108 $bazname = 'baz' . rand(0, 100);
109 $baz_user_id = wp_create_user( $bazname, 'baz', $bazname . '@example.com' );
110 assert( '$baz_user_id instanceof WP_Error === false');
111
112 // this user is deleted, the group relation must be deleted automatically
113 $dolname = 'dol' . rand(0, 100);
114 $dol_user_id = wp_create_user( $dolname, 'dol', $dolname . ' @example.com' );
115 assert( '$dol_user_id instanceof WP_Error === false');
116
117 // this user is a simple editor, used to test WordPress capabilities
118 $editorname = 'rotide' . rand(0, 100);
119 $editor_user_id = wp_create_user( $editorname, 'rotide', $editorname . '@example.com' );
120 assert( '$editor_user_id instanceof WP_Error === false');
121 if ( !( $editor_user_id instanceof WP_Error ) ) {
122 $editor_user = new WP_User( $editor_user_id );
123 $editor_user->set_role( 'editor' );
124 } else {
125 $editor_user_id = false;
126 }
127
128 // *** users & groups ***
129
130 // add valid users to groups
131 // echo "foo user id: $foo_user_id group: $fruits_group_id<br/>";
132 assert( 'Groups_User_Group::create(array( "user_id" => $foo_user_id, "group_id" => $fruits_group_id ) )' );
133 assert( 'Groups_User_Group::create(array( "user_id" => $bar_user_id, "group_id" => $lemon_group_id ) )' );
134 assert( 'Groups_User_Group::create(array( "user_id" => $baz_user_id, "group_id" => $banana_group_id ) )' );
135 assert( 'Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => $sweet_group_id ) )' );
136
137 // add invalid user to group
138 assert( 'Groups_User_Group::create(array( "user_id" => -1, "group_id" => $sweet_group_id ) ) === false' );
139
140 // add valid user to invalid group
141 assert( 'Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => -1 ) ) === false' );
142
143 // define capabilities for groups
144 assert( 'Groups_Group_Capability::create( array( "group_id" => $fruits_group_id, "capability_id" => $dance_capability_id ) )' );
145 assert( 'Groups_Group_Capability::create( array( "group_id" => $sour_group_id, "capability_id" => $sing_capability_id ) )' );
146
147 // define capabilities for users
148 assert( 'Groups_User_Capability::create( array( "user_id" => $foo_user_id, "capability_id" => $clap_capability_id ) )' );
149 assert( 'Groups_User_Capability::create( array( "user_id" => $baz_user_id, "capability_id" => $clap_capability_id ) )' );
150
151 // check groups that can dance (all)
152 // just reading will not check the hierarchy of course ...
153 assert( 'Groups_Group_Capability::read( $fruits_group_id, $dance_capability_id )' );
154 assert( 'Groups_Group_Capability::read( $sweet_group_id, $dance_capability_id ) === false' );
155 assert( 'Groups_Group_Capability::read( $banana_group_id, $dance_capability_id ) === false' );
156 assert( 'Groups_Group_Capability::read( $sour_group_id, $dance_capability_id ) === false' );
157 assert( 'Groups_Group_Capability::read( $lemon_group_id, $dance_capability_id ) === false' );
158 // same for check on groups that can sing
159 assert( 'Groups_Group_Capability::read( $fruits_group_id, $sing_capability_id ) === false' );
160 assert( 'Groups_Group_Capability::read( $sweet_group_id, $sing_capability_id ) === false' );
161 assert( 'Groups_Group_Capability::read( $banana_group_id, $sing_capability_id ) === false' );
162 assert( 'Groups_Group_Capability::read( $sour_group_id, $sing_capability_id )' );
163 assert( 'Groups_Group_Capability::read( $lemon_group_id, $sing_capability_id ) === false' );
164
165 // hierarchical groups
166 $fruits_group = new Groups_Group( $fruits_group_id );
167 $sweet_group = new Groups_Group( $sweet_group_id );
168 $banana_group = new Groups_Group( $banana_group_id );
169 $sour_group = new Groups_Group( $sour_group_id );
170 $lemon_group = new Groups_Group( $lemon_group_id );
171
172 // retrieve users
173 assert( 'count( $fruits_group->users ) > 0' );
174
175 // all should be able to "dance" : check by capability label ...
176 assert( '$fruits_group->can( "dance" )' );
177 assert( '$sweet_group->can( "dance" )' );
178 assert( '$banana_group->can( "dance" )' );
179 assert( '$sour_group->can( "dance" )' );
180 assert( '$lemon_group->can( "dance" )' );
181 // ... or id
182 assert( '$fruits_group->can( $dance_capability_id )' );
183 assert( '$sweet_group->can( $dance_capability_id )' );
184 assert( '$banana_group->can( $dance_capability_id )' );
185 assert( '$sour_group->can( $dance_capability_id )' );
186 assert( '$lemon_group->can( $dance_capability_id )' );
187
188 // only sour and lemon can sing:
189 assert( '!$fruits_group->can( "sing" )' );
190 assert( '!$sweet_group->can( "sing" )' );
191 assert( '!$banana_group->can( "sing" )' );
192 assert( '$sour_group->can( "sing" )' );
193 assert( '$lemon_group->can( "sing" )' );
194 // ... or id
195 assert( '!$fruits_group->can( $sing_capability_id )' );
196 assert( '!$sweet_group->can( $sing_capability_id )' );
197 assert( '!$banana_group->can( $sing_capability_id )' );
198 assert( '$sour_group->can( $sing_capability_id )' );
199 assert( '$lemon_group->can( $sing_capability_id )' );
200
201 // no group can clap
202 assert( '!$fruits_group->can( $clap_capability_id )' );
203 assert( '!$sweet_group->can( $clap_capability_id )' );
204 assert( '!$banana_group->can( $clap_capability_id )' );
205 assert( '!$sour_group->can( $clap_capability_id )' );
206 assert( '!$lemon_group->can( $clap_capability_id )' );
207
208 // user capabilities
209 $foo = new Groups_User( $foo_user_id );
210 $dol = new Groups_User( $dol_user_id );
211 $baz = new Groups_User( $baz_user_id );
212 $bar = new Groups_User( $bar_user_id );
213
214 assert( '$foo->can( "dance" )' );
215 assert( '$dol->can( "dance" )' );
216 assert( '$baz->can( "dance" )' );
217 assert( '$bar->can( "dance" )' );
218
219 assert( '$foo->can( $dance_capability_id )' );
220 assert( '$dol->can( $dance_capability_id )' );
221 assert( '$baz->can( $dance_capability_id )' );
222 assert( '$bar->can( $dance_capability_id )' );
223
224 assert( '!$foo->can( "sing" )' );
225 assert( '!$dol->can( "sing" )' );
226 assert( '!$baz->can( "sing" )' );
227 assert( '$bar->can( "sing" )' );
228
229 assert( '!$foo->can( $sing_capability_id )' );
230 assert( '!$dol->can( $sing_capability_id )' );
231 assert( '!$baz->can( $sing_capability_id )' );
232 assert( '$bar->can( $sing_capability_id )' );
233
234 // only foo & baz can clap
235 assert( '$foo->can( "clap" )' );
236 assert( '!$dol->can( "clap" )' );
237 assert( '$baz->can( "clap" )' );
238 assert( '!$bar->can( "clap" )' );
239
240 assert( '$foo->can( $clap_capability_id )' );
241 assert( '!$dol->can( $clap_capability_id )' );
242 assert( '$baz->can( $clap_capability_id )' );
243 assert( '!$bar->can( $clap_capability_id )' );
244
245 // user can not what is not defined
246 assert( '!$foo->can( null )' );
247 assert( '!$dol->can( null )' );
248 assert( '!$baz->can( null )' );
249 assert( '!$bar->can( null )' );
250
251 assert( '!$foo->can( "bogus" )' );
252 assert( '!$dol->can( "bogus" )' );
253 assert( '!$baz->can( "bogus" )' );
254 assert( '!$bar->can( "bogus" )' );
255
256 // groups can not what is not defined
257 assert( '!$fruits_group->can( null )' );
258 assert( '!$sweet_group->can( null )' );
259 assert( '!$banana_group->can( null )' );
260 assert( '!$sour_group->can( null )' );
261 assert( '!$lemon_group->can( null )' );
262
263 assert( '!$fruits_group->can( "bogus" )' );
264 assert( '!$sweet_group->can( "bogus" )' );
265 assert( '!$banana_group->can( "bogus" )' );
266 assert( '!$sour_group->can( "bogus" )' );
267 assert( '!$lemon_group->can( "bogus" )' );
268
269 // test WordPress capabilities
270 $administrator = new Groups_User( 1 );
271 assert( '$administrator->can( "activate_plugins" )' );
272
273 if ( $editor_user_id ) {
274 $editor = new Groups_User( $editor_user_id );
275 assert( '$editor->can( "edit_posts" )' );
276 assert( '!$editor->can( "activate_plugins" )' );
277 }
278
279 if ( is_multisite() ) {
280 // $randext = rand( 0, 100 );
281 // $wpmu_test_user_id = wp_create_user( 'wpmu_test_user' . $randext, 'wpmu_test_user' );
282 // assert( '$wpmu_test_user_id instanceof WP_Error === false');
283 // @todo create a blog => must create new tables
284 // wpmu_create_blog( "groups_wpmu_" . $randext, "groups_wpmu_" . $randext, "Groups WPMU Test", $wpmu_test_user_id );
285 // @todo add user to new blog
286 // @todo switch to new blog
287 // @todo check that new user is in "Registered" group
288 // @todo switch to current blog
289 }
290
291 //
292 // PART 2 : delete test data
293 //
294
295 if ( is_multisite() ) {
296 // @todo delete new blog
297 }
298
299 // remove capabilities from groups
300 assert( 'Groups_Group_Capability::delete( $fruits_group_id, $dance_capability_id )' );
301
302 // remove users from groups
303 assert( 'Groups_User_Group::delete($foo_user_id, $fruits_group_id)' );
304 assert( 'Groups_User_Group::delete($bar_user_id, $lemon_group_id)' );
305 // baz must be deleted from user_group when banana group is deleted
306
307 // invalid remove user from group
308 assert( 'Groups_User_Group::delete($foo_user_id, $banana_group_id) === false' );
309
310 // delete test users
311 include_once( ABSPATH . '/wp-admin/includes/user.php' );
312 if ( $foo_user_id && !( $foo_user_id instanceof WP_Error ) ) {
313 assert( 'wp_delete_user( $foo_user_id ) === true' );
314 }
315 if ( $bar_user_id && !( $bar_user_id instanceof WP_Error ) ) {
316 assert( 'wp_delete_user( $bar_user_id ) === true' );
317 }
318 if ( $dol_user_id && !( $dol_user_id instanceof WP_Error ) ) {
319 assert( 'wp_delete_user( $dol_user_id ) === true' );
320 if ( $sweet_group_id ) {
321 // see above, this user must have been removed from the group upon its deletion
322 assert( 'Groups_User_Group::read( $dol_user_id, $sweet_group_id ) === false' );
323 }
324 }
325 if ( $editor_user_id && !( $editor_user_id instanceof WP_Error ) ) {
326 assert( 'wp_delete_user( $editor_user_id ) === true' );
327 }
328 // fail to delete inexisting capabilities
329 assert( 'Groups_Capability::delete( -1 ) === false' );
330
331 // delete valid test capabilities
332 if ( $sing_capability_id ) {
333 assert( 'Groups_Capability::delete( $sing_capability_id ) !== false' );
334 }
335 if ( $dance_capability_id ) {
336 assert( 'Groups_Capability::delete( $dance_capability_id ) !== false' );
337 }
338 if ( $clap_capability_id ) {
339 assert( 'Groups_Capability::delete( $clap_capability_id ) !== false' );
340 }
341 // baz shouldn't be able to clap if there's no clapping capability anymore
342 if ( $baz_user_id && !( $baz_user_id instanceof WP_Error ) ) {
343 assert( '!$baz->can( "clap" )' );
344 }
345
346 // fail to delete inexisting group
347 assert( 'Groups_Group::delete( -1 ) === false' );
348
349 // delete invalid test group if creation was successful
350 if ( $bogus_group_id ) {
351 assert( 'Groups_Group::delete( $bogus_group_id )' );
352 }
353
354 // delete valid test groups
355 if ( $fruits_group_id ) {
356 assert( 'Groups_Group::delete( $fruits_group_id )' );
357 }
358 if ( $sweet_group_id ) {
359 assert( 'Groups_Group::delete( $sweet_group_id )' );
360 }
361 if ( $sour_group_id ) {
362 assert( 'Groups_Group::delete( $sour_group_id )' );
363 }
364 if ( $lemon_group_id ) {
365 assert( 'Groups_Group::delete( $lemon_group_id )');
366 }
367 if ( $banana_group_id ) {
368 assert( 'Groups_Group::delete( $banana_group_id )' );
369 assert( 'Groups_User_Group::delete($baz_user_id, $banana_group_id ) === false' );
370 }
371 // this user must not be deleted before as it is used to test that its
372 // relationship with the banana group is resolved when the group is deleted
373 if ( $baz_user_id && !( $baz_user_id instanceof WP_Error ) ) {
374 assert( 'wp_delete_user( $baz_user_id ) === true' );
375 }
376 }
377
378 $active_plugins = get_option( 'active_plugins', array() );
379 $active_sitewide_plugins = array();
380 if ( is_multisite() ) {
381 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
382 }
383 if ( in_array( 'groups/groups.php', $active_plugins ) || key_exists( 'groups/groups.php', $active_sitewide_plugins ) ) {
384 if ( !current_user_can( GROUPS_ADMINISTER_GROUPS ) ) {
385 wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
386 } else {
387 $run = isset( $_POST['run'] ) ? $_POST['run'] : null;
388 switch( $run ) {
389 case 'run' :
390 if ( !isset( $_POST['groups-test-nonce'] ) || !wp_verify_nonce( $_POST['groups-test-nonce'], 'run-tests' ) ) {
391 wp_die( __( 'Access denied.', GROUPS_PLUGIN_DOMAIN ) );
392 }
393 echo '<h1>Running tests for <i>Groups</i> plugin ...</h1>';
394 groups_tests();
395 echo '<h2>Finished.</h2>';
396 break;
397 default :
398 $url = get_bloginfo( 'url' );
399 echo '<p style="color:#f00; font-weight:bold;">';
400 echo 'DO NOT CONTINUE UNLESS YOU KNOW WHAT YOU ARE DOING.';
401 echo '</p>';
402 echo '<ul>';
403 echo '<li>This will run tests for the Groups plugin on this site.</li>';
404 echo '<li>Unless you are a developer who knows what she or he is doing, you do not need to do this and you do not want to proceed.</li>';
405 echo '<li>It may <strong>completely destroy your site</strong>.</li>';
406 echo '<li>Run only at your own risk, do not blame anyone if something goes wrong.</li>';
407 echo '<li>You <strong>agree to be solely responsible for any damage</strong> this may cause to the site.';
408 echo '<li>Make a full backup of your site and database before you continue.</li>';
409 echo '<li>If in doubt, <strong><a href="' . $url . '">do not continue</a></strong>.</li>';
410 echo '</ul>';
411 echo '<form action="" method="post">';
412 echo '<input name="run" value="run" type="hidden" />';
413 echo '<input type="submit" value="Go" />';
414 wp_nonce_field( 'run-tests', 'groups-test-nonce', true, true );
415 echo '</form>';
416 }
417
418 }
419 } else {
420 echo 'The <i>Groups</i> plugin is not active, not running tests.';
421 }
422
423 } // ABSPATH defined
424