Newer
Older
<?php
/**
* @file
* Unit tests for Publish Content module.
*/
/**
* We test to ensure we are not messing up with the default Drupal
* access for view node i.e. a owner of a node can view it even if unpublished.
*/
John Ennew
committed
abstract class PublishContentWebTestBase extends DrupalWebTestCase {
/**
* Perform a GET operation on a node.
*
* This will check the response to access some operation via
* the URL of a node. In the case of 'publish' or 'unpublish'
* it will first visit the view of a node so that the relevant
* tabs can be generated.
*
* @param int $nid
* The node nid
* @param string $op
* An operation such as 'view', 'edit', 'publish', 'unpublish'
* @param int $expected_response
* The expexted response code. If the user should not be able to
* see the 'publish' or 'unpublish' tabs, set this to 403, otherwise
* 200.
* @param string $msg
* (optional) An assertion log message.
*/
public abstract function assertNodeOperationAccess($nid, $op, $expected_response, $msg = '');
/**
* Assert the status of a given node.
*
* @param int $nid
* The node nid to check
* @param int $status
* Either 1 for published or 0 for unpublished
*/
public function assertNodeStatus($nid, $status, $msg = '') {
$node = node_load($nid, NULL, TRUE);
$msg = !empty($msg) ? $msg : t('Node status is @actual, expecting @expected', array('@actual' => $node->status, '@expected' => $status));
$this->assertEqual($node->status, $status, $msg);
/**
* Set the status of a node.
*
* @param node|int $node
* A loaded node object or node nid
* @param int $status
* The status to set, 1 for published, 0 for unpublished.
*/
public function setNodeStatus($node, $status, $msg = '') {
$node = is_object($node) ? $node : node_load($node);
if ($node->status != $status) {
$node->status = $status;
node_save($node);
}
/**
* Check the current user session forbids publish of a given node.
*
* @param node $node
* The node object to test against.
*/
public function assertCurrentUserCannotPublish($node) {
$status = $node->status;
$username = $this->loggedInUser->name;
$this->setNodeStatus($node, 1, 'Start test with a published node');
$this->assertNodeOperationAccess($node->nid, 'publish', 403, $username . ' cannot publish the published node');
$this->assertNodeStatus($node->nid, 1, 'node should be still published');
$this->assertNodeOperationAccess($node->nid, 'view', 200, $username . ' can view the published node');
$this->setNodeStatus($node, 0);
$this->assertNodeOperationAccess($node->nid, 'publish', 403, $username . ' cannot publish the unpublished node');
$this->assertNodeStatus($node->nid, 0, 'node should be still unpublished');
$this->setNodeStatus($node, $status, 'Reset the nodes status');
/**
* Check the current user session cannot unpublish a given node.
*
* @param node $node
* The node object to test against.
*/
public function assertCurrentUserCannotUnpublish($node) {
$status = $node->status;
$username = $this->loggedInUser->name;
$this->setNodeStatus($node, 1, 'Start test with a published node');
$this->assertNodeOperationAccess($node->nid, 'unpublish', 403, $username . ' cannot unpublish the published node');
$this->assertNodeStatus($node->nid, 1, 'node should be still published');
$this->assertNodeOperationAccess($node->nid, 'view', 200, $username . ' can view the published node');
$this->setNodeStatus($node, 0);
$this->assertNodeOperationAccess($node->nid, 'unpublish', 403, $username . ' cannot unpublish an unpublished node');
$this->assertNodeStatus($node->nid, 0, 'node should be still unpublished');
$this->setNodeStatus($node, $status, 'Reset the nodes status');
malaussene
committed
}
/**
* Check the current user session can publish a given node.
*
* @param node $node
* The node object to test against.
*/
public function assertCurrentUserCanPublish($node) {
$status = $node->status;
$username = $this->loggedInUser->name;
$this->setNodeStatus($node, 1, 'Start test with a published node');
$this->assertNodeOperationAccess($node->nid, 'publish', 403, $username . ' cannot access the publish callback for a node which is already published.');
$this->assertNodeOperationAccess($node->nid, 'view', 200, $username . ' can view the published node');
$this->setNodeStatus($node, 0);
$this->assertNodeOperationAccess($node->nid, 'view', 200, $username . ' can view unpublished node');
$this->assertNodeOperationAccess($node->nid, 'publish', 200, $username . ' can access publish callback on an unpublished node');
$this->assertNodeStatus($node->nid, 1, 'node should now be published');
$this->setNodeStatus($node, $status, 'Reset the nodes status');
/**
* Check the current user session can unpublish a node.
*
* @param node $node
* The node to test against.
*/
public function assertCurrentUserCanUnpublish($node) {
$status = $node->status;
$username = $this->loggedInUser->name;
$this->setNodeStatus($node, 1, 'Start test with a published node');
$this->assertNodeOperationAccess($node->nid, 'unpublish', 200, $username . ' can access unpublish callback on a published node');
$this->assertNodeStatus($node->nid, 0, 'Node should now be unpublished');
$this->assertNodeOperationAccess($node->nid, 'view', 200, $username . ' can view the unpublished node.');
$this->assertNodeOperationAccess($node->nid, 'unpublish', 403, $username . ' cannot access the unpublish callback of an unpublished node');
$this->assertNodeStatus($node->nid, 0, 'Node should still be unpublished');
$this->setNodeStatus($node, $status, 'Reset the nodes status');
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/**
* Assert the current user can publish a node from the listing test page.
*/
public function assertCanPublishFromLinksPage($node) {
$status = $node->status;
$this->setNodeStatus($node, 0, 'Start test with an unpublished node');
$this->drupalGet('publishcontent-links');
$this->assertResponse(200);
$this->assertLink('publish-' . $node->nid);
$this->assertNoLink('unpublish-' . $node->nid);
$this->clickLink('publish-' . $node->nid);
$this->assertResponse(200);
$this->assertNodeStatus($node->nid, 1);
$this->setNodeStatus($node, $status, 'Reset status');
}
/**
* Assert the current user cannot publish a node from the listing test page.
*/
public function assertCannotPublishFromLinksPage($node) {
$status = $node->status;
$this->setNodeStatus($node, 0, 'Start test with an unpublished node');
$this->drupalGet('publishcontent-links');
$this->assertResponse(200);
$this->assertNoLink('publish-' . $node->nid);
$this->assertNoLink('unpublish-' . $node->nid);
$this->setNodeStatus($node, $status, 'Reset status');
}
/**
* Assert the current user can unpublish a node from the listing test page.
*/
public function assertCanUnpublishFromLinksPage($node) {
$status = $node->status;
$this->setNodeStatus($node, 1, 'Start test with a published node');
$this->drupalGet('publishcontent-links');
$this->assertResponse(200);
$this->assertLink('unpublish-' . $node->nid);
$this->assertNoLink('publish-' . $node->nid);
$this->clickLink('unpublish-' . $node->nid);
$this->assertResponse(200);
$this->assertNodeStatus($node->nid, 0);
$this->setNodeStatus($node, $status, 'Reset status');
}
/**
* Assert the current user cannot unpublish a node from the listing test page.
*/
public function assertCannotUnpublishFromLinksPage($node) {
$status = $node->status;
$this->setNodeStatus($node, 1, 'Start test with a published node');
$this->drupalGet('publishcontent-links');
$this->assertResponse(200);
$this->assertNoLink('publish-' . $node->nid);
$this->assertNoLink('unpublish-' . $node->nid);
$this->setNodeStatus($node, $status, 'Reset status');
}
* Check no publish permission by node owner.
public function testNoPublishPermissionByOwner() {
$web_user = $this->drupalCreateUser(array('access content'));
$this->drupalLogin($web_user);
$node = $this->drupalCreateNode(
array(
'type' => 'page',
'uid' => $web_user->uid,
'status' => 1,
)
);
$this->assertCurrentUserCannotPublish($node);
$this->assertCurrentUserCannotUnpublish($node);
$this->setNodeStatus($node, 0);
$this->assertNodeOperationAccess($node->nid, 'view', 403, 'Node is not accessible by its owner when unpublished.');
* Check publishcontent module does not interfere with the normal Drupal.
*/
public function testNoPermissionAndNotOwner() {
$node = $this->drupalCreateNode(
array(
'type' => 'page',
$this->drupalLogin($this->drupalCreateUser(array('access content')));
$this->assertCurrentUserCannotPublish($node);
$this->assertCurrentUserCannotUnpublish($node);
$this->setNodeStatus($node, 0);
$this->assertNodeOperationAccess($node->nid, 'view', 403, 'Node is not viewable by non owner when unpublished by a user without publish or unpublish permissions');
/**
* Test the combination of publish but not unpublish permissions.
*/
public function testPublishNotUnpublish() {
variable_set('publishcontent_' . $type, TRUE);
$web_user = $this->drupalCreateUser(array(
'access content',
'publish editable ' . $type . ' content',
'view own unpublished content',
'edit own ' . $type . ' content',
));
$node = $this->drupalCreateNode(
array(
'type' => $type,
'uid' => $web_user->uid,
$this->drupalGet('node/' . $node->nid . '/edit');
$this->assertResponse(200);
$this->assertCurrentUserCanPublish($node);
$this->assertCurrentUserCannotUnpublish($node);
/**
* Test the combination of unpublish but not publish.
*/
public function testNotPublishUnpublish() {
$type = 'page';
variable_set('publishcontent_' . $type, TRUE);
$web_user = $this->drupalCreateUser(array(
'access content',
'unpublish any ' . $type . ' content',
'view own unpublished content',
'edit own ' . $type . ' content',
));
$this->drupalLogin($web_user);
$node = $this->drupalCreateNode(
array(
'type' => $type,
'uid' => $web_user->uid,
'status' => 1,
)
);
$this->assertCurrentUserCannotPublish($node);
$this->assertCurrentUserCanUnpublish($node);
/**
* Test the combination of both publish and unpublish.
*/
public function testPublishUnpublish() {
variable_set('publishcontent_' . $type, TRUE);
$web_user_1 = $this->drupalCreateUser(array(
'access content',
'view own unpublished content',
'edit any ' . $type . ' content',
'publish any content',
));
$node1 = $this->drupalCreateNode(
'uid' => $web_user_1->uid,
$this->drupalLogin($web_user_1);
$this->assertCurrentUserCanPublish($node1);
$this->assertCurrentUserCannotUnpublish($node1);
$web_user_2 = $this->drupalCreateUser(array(
'access content',
'view own unpublished content',
'edit any ' . $type . ' content',
'unpublish any content',
));
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
$node2 = $this->drupalCreateNode(
array(
'type' => $type,
'uid' => $web_user_2->uid,
'status' => 1,
)
);
$this->drupalLogin($web_user_2);
$this->assertCurrentUserCannotPublish($node2);
$this->assertCurrentUserCanUnpublish($node2);
$web_user_3 = $this->drupalCreateUser(array(
'access content',
'view own unpublished content',
'edit any ' . $type . ' content',
'publish any content',
'unpublish any content',
));
$node3 = $this->drupalCreateNode(
array(
'type' => $type,
'uid' => $web_user_3->uid,
'status' => 1,
)
);
$this->drupalLogin($web_user_3);
$this->assertCurrentUserCanPublish($node3);
$this->assertCurrentUserCanUnpublish($node3);
John Ennew
committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
/**
* Test basic publish ability using the publishcontent_test module.
*/
public function testBasicPublishCallback() {
$type = 'page';
variable_set('publishcontent_' . $type, TRUE);
variable_set('publishcontent_article', TRUE);
$web_user_1 = $this->drupalCreateUser(array(
'access content',
'publish any content',
));
$web_user_2 = $this->drupalCreateUser(array(
'access content',
'unpublish any content',
));
$web_user_3 = $this->drupalCreateUser(array(
'access content',
'publish any content',
'unpublish any content',
));
$web_user_4 = $this->drupalCreateUser(array(
'access content',
'publish any ' . $type . ' content',
));
$web_user_5 = $this->drupalCreateUser(array(
'access content',
'unpublish any ' . $type . ' content',
));
$web_user_6 = $this->drupalCreateUser(array(
'access content',
'publish any ' . $type . ' content',
'unpublish any ' . $type . ' content',
));
$web_user_7 = $this->drupalCreateUser(array(
'access content',
'publish any article content',
'unpublish any article content',
));
$node = $this->drupalCreateNode(
array(
'type' => $type,
'uid' => 1,
'status' => 0,
)
);
$this->drupalLogin($web_user_1);
$this->assertCanPublishFromLinksPage($node, 'Someone with publish any content can publish page node');
$this->assertCannotUnpublishFromLinksPage($node, 'Someone with publish any content cannot unpublish page node');
$this->drupalLogin($web_user_2);
$this->assertCannotPublishFromLinksPage($node, 'Someone with unpublish any content cannot publish page node');
$this->assertCanUnpublishFromLinksPage($node, 'Someone with unpublish any content can unpublish page node');
$this->drupalLogin($web_user_3);
$this->assertCanPublishFromLinksPage($node, 'Someone with publish and unpublish any content can publish page node');
$this->assertCanUnpublishFromLinksPage($node, 'Someone with publish and unpublish any content can unpublish page node');
$this->drupalLogin($web_user_4);
$this->assertCanPublishFromLinksPage($node, 'Someone with publish any page nodes can publish a page node');
$this->assertCannotUnpublishFromLinksPage($node, 'Someone with publish any page nodes cannot unpublish page node');
$this->drupalLogin($web_user_5);
$this->assertCannotPublishFromLinksPage($node, 'Someone with unpublish any page node cannot publish a page node');
$this->assertCanUnpublishFromLinksPage($node, 'Someone with unpublish any page node can unpublish a page node');
$this->drupalLogin($web_user_6);
$this->assertCanPublishFromLinksPage($node, 'Someone with publish and unpublish any page node can publish a page node');
$this->assertCanUnpublishFromLinksPage($node, 'Someone with publish and unpublish any page node can unpublish a page node');
$this->drupalLogin($web_user_7);
$this->assertCannotPublishFromLinksPage($node, 'Someone with publish any article content cannot publish page content');
$this->assertCannotUnpublishFromLinksPage($node, 'Someone with unpublish any article content cannot unpublish page content');
}
John Ennew
committed
}
/**
* Test permissions with the tab method.
*/
class PublishContentTabTests extends PublishContentWebTestBase {
/**
* Drupal SimpleTest method: return metadata about the test.
*/
public static function getInfo() {
return array(
'name' => t('Publish Content: Tab Tests'),
'description' => t('Executes test suite for Publish Content module with the tab method.'),
'group' => t('Publish Content'),
);
}
/**
* Test setup instructions.
*/
public function setUp() {
parent::setUp('publishcontent', 'publishcontent_test');
John Ennew
committed
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
variable_set('publishcontent_method', PUBLISHCONTENT_METHOD_TABS);
}
/**
* Perform a GET operation on a node.
*
* This will check the response to access some operation via
* the URL of a node. In the case of 'publish' or 'unpublish'
* it will first visit the view of a node so that the relevant
* tabs can be generated.
*
* @param int $nid
* The node nid
* @param string $op
* An operation such as 'view', 'edit', 'publish', 'unpublish'
* @param int $expected_response
* The expexted response code. If the user should not be able to
* see the 'publish' or 'unpublish' tabs, set this to 403, otherwise
* 200.
* @param string $msg
* (optional) An assertion log message.
*/
public function assertNodeOperationAccess($nid, $op, $expected_response, $msg = '') {
if (in_array($op, array('publish', 'unpublish'))) {
$tab_link_text = ucfirst($op);
// Visit the edit page first to generate the tab.
$this->drupalGet("node/{$nid}");
$view_response = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);
if ($view_response != 200) {
$msg .= t('Could not view the node. Response code: @response', array('@response' => $view_response));
$this->assert($expected_response == $view_response, $msg);
return;
}
// Check the tab exists.
$links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $tab_link_text));
if (!isset($links[0])) {
// No tab.
$msg .= t('Could not find a tab called @tab', array('@tab' => $tab_link_text));
$this->assert($expected_response != 200, $msg);
return;
}
// Now visit the tab.
$this->clickLink($tab_link_text);
$node = node_load($nid);
if ($op == 'publish') {
$this->assertText(_publishcontent_get_message($node->nid, $node->title, TRUE),
'Publish content message is visible.');
}
else {
$this->assertText(_publishcontent_get_message($node->nid, $node->title, FALSE),
'Unpublish message is visible.');
}
}
else {
$url = $op == 'view' ? "node/{$nid}" : "node/$nid/$op";
$this->drupalGet($url);
}
$this->assertResponse($expected_response, $msg);
}
John Ennew
committed
}
/**
* Test permissions with the button method.
*/
class PublishContentButtonTests extends PublishContentWebTestBase {
/**
* Drupal SimpleTest method: return metadata about the test.
*/
public static function getInfo() {
return array(
'name' => t('Publish Content: Button Tests'),
'description' => t('Executes test suite for Publish Content module with the button method.'),
'group' => t('Publish Content'),
);
}
/**
* Test setup instructions.
*/
public function setUp() {
parent::setUp('publishcontent', 'publishcontent_test');
John Ennew
committed
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
variable_set('publishcontent_method', PUBLISHCONTENT_METHOD_BUTTON);
}
/**
* Perform a GET operation on a node.
*
* This will check the response to access some operation via
* the URL of a node. In the case of 'publish' or 'unpublish'
* it will first visit the view of a node so that the relevant
* tabs can be generated.
*
* @param int $nid
* The node nid
* @param string $op
* An operation such as 'view', 'edit', 'publish', 'unpublish'
* @param int $expected_response
* The expexted response code. If the user should not be able to
* see the 'publish' or 'unpublish' tabs, set this to 403, otherwise
* 200.
* @param string $msg
* (optional) An assertion log message.
*/
public function assertNodeOperationAccess($nid, $op, $expected_response, $msg = '') {
if (in_array($op, array('publish', 'unpublish'))) {
$button_text = t(ucfirst($op));
// Visit the edit page first to generate the tab.
$this->drupalGet("node/{$nid}/edit");
$view_response = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);
if ($view_response != 200) {
$msg .= t('Could not view the node. Response code: @response', array('@response' => $view_response));
$this->assert($expected_response == $view_response, $msg);
return;
}
// Find the button.
$buttons = $this->xpath('//input[@value=:label]', array(':label' => $button_text));
if (!isset($buttons[0])) {
// No button.
$msg .= t('Could not find a button called @button', array('@button' => $button_text));
$this->assert($expected_response != 200, $msg);
return;
}
// Submit the form.
$this->drupalPost("node/{$nid}/edit", array(), $button_text);
}
else {
$url = $op == 'view' ? "node/{$nid}" : "node/$nid/$op";
$this->drupalGet($url);
}
$this->assertResponse($expected_response, $msg);
}
}
/**
* Test permissions with the tab method.
*/
class PublishContentCheckboxTests extends PublishContentWebTestBase {
/**
* Drupal SimpleTest method: return metadata about the test.
*/
public static function getInfo() {
return array(
'name' => t('Publish Content: Checkbox Tests'),
'description' => t('Executes test suite for Publish Content module with the checkbox method.'),
'group' => t('Publish Content'),
);
}
/**
* Test setup instructions.
*/
public function setUp() {
parent::setUp('publishcontent', 'publishcontent_test');
John Ennew
committed
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
variable_set('publishcontent_method', PUBLISHCONTENT_METHOD_NONE);
}
/**
* Perform a GET operation on a node.
*
* This will check the response to access some operation via
* the URL of a node. In the case of 'publish' or 'unpublish'
* it will first visit the view of a node so that the relevant
* tabs can be generated.
*
* @param int $nid
* The node nid
* @param string $op
* An operation such as 'view', 'edit', 'publish', 'unpublish'
* @param int $expected_response
* The expexted response code. If the user should not be able to
* see the 'publish' or 'unpublish' tabs, set this to 403, otherwise
* 200.
* @param string $msg
* (optional) An assertion log message.
*/
public function assertNodeOperationAccess($nid, $op, $expected_response, $msg = '') {
if (in_array($op, array('publish', 'unpublish'))) {
// Visit the edit page first to check for the published checkbox.
$this->drupalGet("node/{$nid}/edit");
$view_response = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);
if ($view_response != 200) {
$msg .= t('Could not edit the node. Response code: @response', array('@response' => $view_response));
$this->assert($expected_response == $view_response, $msg);
return;
}
// Check the checkbox exists.
$elements = $this->xpath('//input[@id=:id]', array(':id' => 'edit-status'));
if (!isset($elements[0])) {
// No checkboxes.
$msg .= t('Published status checkbox is not accessible.');
$this->assert($expected_response != 200, $msg);
return;
}
// At this point the response code for checkboxes is irrelevant, if
// they can access the edit page and see the checkbox, they can edit it.
$expected_response = 200;
// Tick or untick the published checkbox and submit the form.
$edit_status = ($op == 'publish');
$this->drupalPost("node/{$nid}/edit", array('status' => $edit_status), t('Save'));
}
else {
$url = $op == 'view' ? "node/{$nid}" : "node/$nid/$op";
$this->drupalGet($url);
}
$this->assertResponse($expected_response, $msg);
}
Jonathan McLaughlin
committed
/**
* Test access to the node add page is working.
*/
public function testAccessNodeAdd() {
$type = 'page';
variable_set('publishcontent_' . $type, TRUE);
$web_user_1 = $this->drupalCreateUser(array(
'access content',
'view own unpublished content',
'create ' . $type . ' content',
'publish editable content',
'unpublish editable content',
));
$this->drupalLogin($web_user_1);
$this->drupalGet('node/add/' . $type);
$this->assertResponse(200);
$this->assertFieldChecked('edit-status', t('Ensure the publish checkbox is available.'));
}