diff --git a/tests/external_node_update.test b/tests/external_node_update.test new file mode 100644 index 0000000..1d7f0d0 --- /dev/null +++ b/tests/external_node_update.test @@ -0,0 +1,197 @@ + 'External node update', + 'description' => 'Test if nodes are correctly moderated when updated by third party modules.', + 'group' => 'Workbench Moderation', + ); + } + + /** + * {@inheritdoc} + */ + function setUp($modules = array()) { + // Enable a test module that will publish and unpublish nodes for us. + parent::setUp(array_merge($modules, array('workbench_moderation_test'))); + + $this->drupalLogin($this->moderator_user); + } + + /** + * Tests if nodes can be moderated by third party modules. + */ + function testNodeSave() { + // Create a brand new unpublished node programmatically. + $settings = array( + 'title' => $this->randomName(), + 'type' => $this->content_type, + 'status' => NODE_NOT_PUBLISHED, + ); + $this->node = $this->drupalCreateNode($settings); + + // Assert that the node is initially in state draft and not published. + $expected = array('state' => 'draft'); + $this->assertModerationStatus($expected, 'current', 'The moderation status is correct for a newly created node.'); + $this->assertNoPublishedRecord('A newly created node does not have a published entry in the node history table.'); + $this->assertPublicationState(FALSE, 'A newly created node is not published.'); + + // Resave the node and check that the status doesn't change. + $this->assertNodeUnchangedAfterResave(); + + // Publish the node in an external module and check that the moderation + // state changes accordingly. + $this->drupalGet('workbench_moderation_test/' . $this->node->nid . '/publish'); + $this->refreshNode(); + $expected = array('state' => 'published'); + $this->assertModerationStatus($expected, 'current', 'The moderation state changed to "published" if the node is published externally.'); + $this->assertModerationStatus($expected, 'published', 'A published moderation state record is created when the node is published externally.'); + $this->assertPublicationState(TRUE, 'A node which is published externally is actually published.'); + + // Resave the node and check that the status doesn't change. + $this->assertNodeUnchangedAfterResave(); + + // Unpublish the node in an external module and check that the moderation + // state changes accordingly. + $this->drupalGet('workbench_moderation_test/' . $this->node->nid . '/unpublish'); + $this->refreshNode(); + $expected = array('state' => 'draft'); + $this->assertModerationStatus($expected, 'current', 'The moderation state changed to "draft" if the node is unpublished externally.'); + $this->assertNoPublishedRecord('The published moderation state record is removed when the node is unpublished externally.'); + $this->assertPublicationState(FALSE, 'A node which is unpublished externally is actually unpublished.'); + + // Resave the node and check that the status doesn't change. + $this->assertNodeUnchangedAfterResave(); + } + + /** + * Checks that the tested node doesn't change after it is resaved. + * + * @return + * TRUE if the assertion succeeded, FALSE otherwise. + */ + public function assertNodeUnchangedAfterResave() { + // Retrieve the current status of the node. + $current = $this->getModerationRecord('current'); + $published = $this->getModerationRecord('published'); + $status = $this->node->status; + + // Resave the node in an external module. + $this->drupalGet('workbench_moderation_test/' . $this->node->nid); + $this->refreshNode(); + + // Check if the status remains unchanged. + $success = TRUE; + $success |= $this->assertModerationStatus($current, 'current', 'The current moderation status doesn\'t change after resaving the node.'); + if ($published) { + $success |= $this->assertModerationStatus($published, 'published', 'The published moderation status doesn\'t change after resaving the node.'); + } + else { + $success |= $this->assertNoPublishedRecord('The node does not get a published entry in the node history table after resaving.'); + } + $success |= $this->assertEqual($status, $this->node->status, 'The publication state remains unchanged after resaving.'); + + return $this->assertTrue($success, 'The node has remained unchanged after resaving.'); + } + + /** + * Checks if the node history table matches the expected values. + * + * @param array $expected + * An associative array containing expected moderation status values. + * @param string $status + * Which status to assert. Can be either 'current' or 'published'. + * @param $message + * The message to display along with the assertion. + * + * @return + * TRUE if the assertion succeeded, FALSE otherwise. + */ + public function assertModerationStatus(array $expected, $status = 'current', $message = '') { + $record = $this->getModerationRecord($status); + $success = TRUE; + foreach ($expected as $key => $value) { + $success |= $this->assertEqual($value, $record[$key], format_string('Found value %value for %key, expected %expected.', array('%key' => $key, '%value' => $record[$key], '%expected' => $value))); + } + + return $this->assertTrue($success, $message); + } + + /** + * Checks if the node is not marked as 'published' in the node history table. + * + * @param $message + * The message to display along with the assertion. + * + * @return + * TRUE if the assertion succeeded, FALSE otherwise. + */ + public function assertNoPublishedRecord($message = '') { + $record = $this->getModerationRecord('published'); + return $this->assertFalse($record, $message); + } + + /** + * Checks that the test node has the expected publication state. + * + * @param bool $expected + * TRUE if the the node should be published, FALSE otherwise. + * @param string $message + * The message to display along with the assertion. + * + * @return type + */ + public function assertPublicationState($expected, $message = '') { + return $this->assertEqual($expected, $this->node->status, $message); + } + + /** + * Refreshes the test node so it matches the actual state in the database. + */ + public function refreshNode() { + $this->node = node_load($this->node->nid, NULL, TRUE); + } + + /** + * Returns a moderation status record of the tested node. + * + * @param string $status + * Which status to return. Can be either 'current' or 'published'. + * + * @return array + * The node's record(s) from the {workbench_moderation_node_history} table. + */ + protected function getModerationRecord($status = 'current') { + return db_select('workbench_moderation_node_history', 'nh') + ->fields('nh', array('from_state', 'state', 'published', 'current')) + ->condition('nid', $this->node->nid, '=') + ->condition($status, 1) + ->execute() + ->fetchAssoc(); + } + +} diff --git a/tests/workbench_moderation_test.info b/tests/workbench_moderation_test.info new file mode 100644 index 0000000..0f9e013 --- /dev/null +++ b/tests/workbench_moderation_test.info @@ -0,0 +1,5 @@ +name = Workbench Moderation Test +description = Test module for Workbench Moderation. +package = Workbench +core = 7.x +hidden = TRUE diff --git a/tests/workbench_moderation_test.module b/tests/workbench_moderation_test.module new file mode 100644 index 0000000..f1dc668 --- /dev/null +++ b/tests/workbench_moderation_test.module @@ -0,0 +1,37 @@ + array( + 'title' => 'Publish a node', + 'page callback' => 'workbench_moderation_test_update_node', + 'page arguments' => array(1), + 'access arguments' => array('bypass workbench moderation'), + ), + ); +} + +/** + * Page callback. Publishes, unpublishes or resaves the given node. + * + * @param object $node + * The node to publish, unpublish or resave. + * @param string $action + * Optionally the action to take, either 'publish' or 'unpublish'. If omitted + * the node will be resaved. + */ +function workbench_moderation_test_update_node($node, $action = NULL) { + if (!empty($action)) { + $node->status = $action == 'publish' ? NODE_PUBLISHED : NODE_NOT_PUBLISHED; + } + node_save($node); + return array('#markup' => t('Node status: @status', array('@status' => $node->status ? t('published') : t('unpublished')))); +} diff --git a/workbench_moderation.info b/workbench_moderation.info index f065940..3f9939f 100644 --- a/workbench_moderation.info +++ b/workbench_moderation.info @@ -13,5 +13,6 @@ files[] = includes/workbench_moderation_handler_filter_state.inc files[] = includes/workbench_moderation_handler_filter_moderated_type.inc files[] = includes/workbench_moderation_handler_filter_user_can_moderate.inc files[] = workbench_moderation.migrate.inc +files[] = tests/external_node_update.test files[] = tests/workbench_moderation.test files[] = tests/workbench_moderation.files.test