diff --git a/scheduler.module b/scheduler.module index 1845e38..ae7a840 100644 --- a/scheduler.module +++ b/scheduler.module @@ -342,8 +342,16 @@ function scheduler_form_alter(&$form, $form_state) { $defaults->unpublish_on = _scheduler_strtotime($defaults->unpublish_on); } - $publishing_required = variable_get('scheduler_publish_required_' . $form['type']['#value'], 0) == 1 && $node->status == 0; - $unpublishing_required = variable_get('scheduler_unpublish_required_' . $form['type']['#value'], 0) == 1 && $node->status == 1; + // A publish_on date is required if the content type option is set and the + // node is being created or it currently has a scheduled publishing date. + $publishing_required = variable_get('scheduler_publish_required_' . $form['type']['#value'], 0) == 1 + && (empty($node->nid) || ($node->status == 0 && !empty($node->publish_on))); + + // An unpublish_on date is required if the content type option is set and + // the node is being created or the current status is published or the + // node is scheduled to be published. + $unpublishing_required = variable_get('scheduler_unpublish_required_' . $form['type']['#value'], 0) == 1 + && (empty($node->nid) || $node->status == 1 || !empty($node->publish_on)); $fieldset_extended = ( (isset($defaults->publish_on) && $defaults->publish_on != 0) diff --git a/scheduler.test b/scheduler.test index c12567b..479a569 100644 --- a/scheduler.test +++ b/scheduler.test @@ -133,4 +133,194 @@ class SchedulerTestCase extends DrupalWebTestCase { $this->assertTrue($node->status, 'The node with publication date in the past and the "schedule" behavior has now been published by cron.'); } + /** + * Tests creating and editing nodes with required scheduling enabled. + */ + function testRequiredScheduling() { + $this->drupalLogin($this->admin_user); + + // Define test scenarios with expected results. + $test_cases = array( + // The 1-10 numbering used below matches the test cases described in + // http://drupal.org/node/1198788#comment-7816119 + + // A. Test scenarios that require scheduled publishing. + + // When creating a new unpublished node it is required to enter a + // publication date. + array( + 'id' => 1, + 'required' => 'publish', + 'operation' => 'add', + 'status' => 0, + 'expected' => 'required', + 'message' => 'When scheduled publishing is required and a new unpublished node is created, entering a date in the publish on field is required.', + ), + + // When creating a new published node it is required to enter a + // publication date. The node will be unpublished on form submit. + array( + 'id' => 2, + 'required' => 'publish', + 'operation' => 'add', + 'status' => 1, + 'expected' => 'required', + 'message' => 'When scheduled publishing is required and a new published node is created, entering a date in the publish on field is required.', + ), + + // When editing a published node it is not needed to enter a publication + // date since the node is already published. + array( + 'id' => 3, + 'required' => 'publish', + 'operation' => 'edit', + 'scheduled' => 0, + 'status' => 1, + 'expected' => 'not required', + 'message' => 'When scheduled publishing is required and an existing published, unscheduled node is edited, entering a date in the publish on field is not required.', + ), + + // When editing an unpublished node that is scheduled for publication it + // is required to enter a publication date. + array( + 'id' => 4, + 'required' => 'publish', + 'operation' => 'edit', + 'scheduled' => 1, + 'status' => 0, + 'expected' => 'required', + 'message' => 'When scheduled publishing is required and an existing unpublished, scheduled node is edited, entering a date in the publish on field is required.', + ), + + // When editing an unpublished node that is not scheduled for publication + // it is not required to enter a publication date since this means that + // the node has already gone through a publication > unpublication cycle. + array( + 'id' => 5, + 'required' => 'publish', + 'operation' => 'edit', + 'scheduled' => 0, + 'status' => 0, + 'expected' => 'not required', + 'message' => 'When scheduled publishing is required and an existing unpublished, unscheduled node is edited, entering a date in the publish on field is not required.', + ), + + // B. Test scenarios that require scheduled unpublishing. + + // When creating a new unpublished node it is required to enter an + // unpublication date since it is to be expected that the node will be + // published at some point and should subsequently be unpublished. + array( + 'id' => 6, + 'required' => 'unpublish', + 'operation' => 'add', + 'status' => 0, + 'expected' => 'required', + 'message' => 'When scheduled unpublishing is required and a new unpublished node is created, entering a date in the unpublish on field is required.', + ), + + // When creating a new published node it is required to enter an + // unpublication date. + array( + 'id' => 7, + 'required' => 'unpublish', + 'operation' => 'add', + 'status' => 1, + 'expected' => 'required', + 'message' => 'When scheduled unpublishing is required and a new published node is created, entering a date in the unpublish on field is required.', + ), + + // When editing a published node it is required to enter an unpublication + // date. + array( + 'id' => 8, + 'required' => 'unpublish', + 'operation' => 'edit', + 'scheduled' => 0, + 'status' => 1, + 'expected' => 'required', + 'message' => 'When scheduled unpublishing is required and an existing published, unscheduled node is edited, entering a date in the unpublish on field is required.', + ), + + // When editing an unpublished node that is scheduled for publication it + // it is required to enter an unpublication date. + array( + 'id' => 9, + 'required' => 'unpublish', + 'operation' => 'edit', + 'scheduled' => 1, + 'status' => 0, + 'expected' => 'required', + 'message' => 'When scheduled unpublishing is required and an existing unpublished, scheduled node is edited, entering a date in the unpublish on field is required.', + ), + + // When editing an unpublished node that is not scheduled for publication + // it is not required to enter an unpublication date since this means that + // the node has already gone through a publication - unpublication cycle. + array( + 'id' => 10, + 'required' => 'unpublish', + 'operation' => 'edit', + 'scheduled' => 0, + 'status' => 0, + 'expected' => 'not required', + 'message' => 'When scheduled unpublishing is required and an existing unpublished, unscheduled node is edited, entering a date in the unpublish on field is not required.', + ), + ); + + foreach ($test_cases as $test_case) { + // Enable required (un)publishing as stipulated by the test case. + variable_set('scheduler_publish_required_page', $test_case['required'] == 'publish'); + variable_set('scheduler_unpublish_required_page', $test_case['required'] == 'unpublish'); + + // Set the default node status, used when creating a new node. + $node_options_page = !empty($test_case['status']) ? array('status') : array(); + variable_set('node_options_page', $node_options_page); + + // To assist viewing and analysing the generated test result pages create + // a text string showing all the test case parameters. + $title_data = array(); + foreach ($test_case as $key => $value) { + if ($key != 'message') { + $title_data[] = $key . ' = ' . $value; + } + } + $title = implode(', ', $title_data); + + // If the test case requires editing a node, we need to create one first. + if ($test_case['operation'] == 'edit') { + $options = array( + 'title' => $title, + 'type' => 'page', + 'status' => $test_case['status'], + 'publish_on' => !empty($test_case['scheduled']) ? strtotime('+ 1 day') : 0, + ); + $node = $this->drupalCreateNode($options); + } + + // Make sure the publication date fields are empty so we can check if they + // throw form validation errors when they are required. + $edit = array( + 'title' => $title, + 'publish_on' => '', + 'unpublish_on' => '', + ); + $path = $test_case['operation'] == 'add' ? 'node/add/page' : 'node/' . $node->nid . '/edit'; + $this->drupalPost($path, $edit, t('Save')); + + // Check for the expected result. + switch ($test_case['expected']) { + case 'required': + $string = t('!name field is required.', array('!name' => ucfirst($test_case['required']) . ' on')); + $this->assertRaw($string, $test_case['id'] . '. ' . $test_case['message']); + break; + + case 'not required': + $string = '@type %title has been ' . ($test_case['operation'] == 'add' ? 'created' : 'updated') . '.'; + $args = array('@type' => 'Basic page', '%title' => $title); + $this->assertRaw(t($string, $args), $test_case['id'] . '. ' . $test_case['message']); + break; + } + } + } }