<?php

/**
 * @file
 * Basic tests for the qforms module.
 */

class QformsBasicTestCase extends DrupalWebTestCase {

  protected $auth_user1;
  protected $auth_user2;

  protected $qform_def = 'a:7:{s:25:"qforms_element_2_textarea";a:9:{s:4:"type";s:8:"textarea";s:6:"delete";s:0:"";s:2:"id";s:25:"qforms_element_2_textarea";s:6:"weight";s:1:"2";s:5:"title";s:30:"Why do you like cars (detail)?";s:11:"description";s:28:"Explain why do you like cars";s:8:"required";i:0;s:7:"visible";i:1;s:4:"size";s:2:"60";}s:27:"qforms_element_3_checkboxes";a:22:{s:4:"type";s:10:"checkboxes";s:6:"delete";s:0:"";s:2:"id";s:27:"qforms_element_3_checkboxes";s:6:"weight";s:1:"3";s:5:"title";s:21:"I like car because...";s:11:"description";s:28:"Reasons why do you like cars";s:8:"required";i:0;s:7:"visible";i:1;s:17:"options_1_default";i:1;s:12:"options_1_id";i:1;s:22:"options_1_option_value";s:20:"I can travel quickly";s:14:"last_option_id";i:1;s:17:"options_3_default";i:0;s:12:"options_3_id";i:3;s:22:"options_3_option_value";s:20:"I have air condition";s:17:"options_4_default";i:0;s:12:"options_4_id";i:4;s:22:"options_4_option_value";s:20:"I just like to drive";s:17:"options_5_default";i:0;s:12:"options_5_id";i:5;s:22:"options_5_option_value";s:19:"I have full comfort";s:5:"other";i:1;}s:23:"qforms_element_4_radios";a:25:{s:4:"type";s:6:"radios";s:6:"delete";s:0:"";s:2:"id";s:23:"qforms_element_4_radios";s:6:"weight";s:1:"4";s:5:"title";s:14:"Favorite brand";s:11:"description";s:19:"Your favorite brand";s:8:"required";i:1;s:7:"visible";i:1;s:17:"options_1_default";i:0;s:12:"options_1_id";i:1;s:22:"options_1_option_value";s:6:"Toyota";s:14:"last_option_id";i:1;s:17:"options_2_default";i:0;s:12:"options_2_id";i:2;s:22:"options_2_option_value";s:2:"VW";s:17:"options_3_default";i:0;s:12:"options_3_id";i:3;s:22:"options_3_option_value";s:4:"Ford";s:17:"options_4_default";i:0;s:12:"options_4_id";i:4;s:22:"options_4_option_value";s:4:"Opel";s:17:"options_5_default";i:0;s:12:"options_5_id";i:5;s:22:"options_5_option_value";s:3:"BMW";s:5:"other";i:1;}s:23:"qforms_element_5_select";a:26:{s:4:"type";s:6:"select";s:6:"delete";s:0:"";s:2:"id";s:23:"qforms_element_5_select";s:6:"weight";s:1:"5";s:5:"title";s:14:"Favorite color";s:11:"description";s:19:"Your favorite color";s:8:"required";i:0;s:7:"visible";i:1;s:17:"options_1_default";i:0;s:12:"options_1_id";i:1;s:22:"options_1_option_value";s:5:"White";s:14:"last_option_id";i:1;s:17:"options_2_default";i:0;s:12:"options_2_id";i:2;s:22:"options_2_option_value";s:4:"Blue";s:17:"options_3_default";i:0;s:12:"options_3_id";i:3;s:22:"options_3_option_value";s:5:"Green";s:17:"options_4_default";i:0;s:12:"options_4_id";i:4;s:22:"options_4_option_value";s:3:"Red";s:17:"options_5_default";i:0;s:12:"options_5_id";i:5;s:22:"options_5_option_value";s:5:"Black";s:8:"multiple";i:0;s:5:"other";i:1;}s:26:"qforms_element_6_textfield";a:9:{s:4:"type";s:9:"textfield";s:6:"delete";s:0:"";s:2:"id";s:26:"qforms_element_6_textfield";s:6:"weight";s:1:"6";s:5:"title";s:31:"Why do you like cars (briefly)?";s:11:"description";s:36:"Briefly explain why do you like cars";s:8:"required";i:1;s:7:"visible";i:1;s:4:"size";s:2:"60";}s:26:"qforms_element_7_textfield";a:9:{s:4:"type";s:9:"textfield";s:6:"delete";s:0:"";s:2:"id";s:26:"qforms_element_7_textfield";s:6:"weight";s:1:"7";s:5:"title";s:17:"Are you a driver?";s:11:"description";s:29:"Do you have a driver licence?";s:8:"required";i:0;s:7:"visible";i:0;s:4:"size";s:2:"20";}s:22:"qforms_last_element_id";i:7;}';

  public static function getInfo() {
    return array(
      'name' => 'Qforms functionality',
      'description' => 'Tests basic functionality in qforms module.',
      'group' => 'Qforms'
    );
  }

  protected function setUp() {
    parent::setUp('qforms');

    $perm = array('create qform content', 'edit own qform content', 'delete own qform content', 'view and submit qform');
    $this->auth_user1 = $this->drupalCreateUser($perm);
    $this->auth_user2 = $this->drupalCreateUser($perm);
  }

  /**
   * Test qform creation from predefined json data.
   */
  public function testQformContent() {
    $this->drupalLogin($this->auth_user1);

    // Create test qform.
    $this->addContent();
    $this->drupalGet('node/1');

    $this->qformsAssertUserForm();

    // Testing of qforms-results screen - befor field population with data.
    $this->drupalGet('node/1/qforms-results');
    $passed = $this->assertText(t('No submission results.'));
    $passed = $passed && $this->assertNoText(t('20 | All results per page. 1 results total.'));
    $this->assert($passed, t('Submission result screen is OK'));

    // Form population with data.
    $this->addData();

    // Test required field.
    $this->drupalGet('node/1');
    $this->drupalPost('node/1', array('qforms_element_6_textfield' => ''), t('Submit'));
    $this->assertText(t('Why do you like cars (briefly)? field is required.'));

    // Testing of qforms-results screen - after field population with data.
    $this->drupalGet('node/1/qforms-results');
    $passed = $this->assertText(t('20 | All results per page. 1 results total.'));
    $this->assert($passed, t('Submission result screen is OK'));

    // Test view of the node previously populated with data.
    $this->drupalGet('node/1/qforms-result/1');
    $passed = $this->assertFieldByName('qforms_element_6_textfield', t('They are very useful'));
    $passed = $passed && $this->assertFieldByName('qforms_element_2_textarea', t('They are very useful since I can travel very quickly'));
    $passed = $passed && $this->assertFieldByName('qforms_element_3_checkboxes[I just like to drive]', t('I just like to drive'));
    $passed = $passed && $this->assertFieldByName('qforms_element_3_checkboxes[qforms_element_3_checkboxes_other]', t('I can transfer weight'));
    $passed = $passed && $this->assertFieldByName('qforms_element_4_radios', t('Toyota'));
    $passed = $passed && $this->assertFieldByName('qforms_element_4_radios_other', t('Mercedes'));
    $passed = $passed && $this->assertFieldByName('qforms_element_5_select', t('Black'));
    $passed = $passed && $this->assertFieldByName('qforms_element_5_select_other', t('Gray'));
    $this->assert($passed, t('View of the node is OK'));

    $this->addData('node/1/qforms-result/1', 'OK');
    $this->assertText('Export results to csv file', t('Ok button take user to the "Subission results" screen.'));

    // Test submission delete.
    // Delete from view and from submission result use same mechamizm
    $this->drupalGet('node/1/qforms-result/1/delete');
    $this->assertText(t('Are you sure you want to delete the submission') . ' 1' . '?');
    $this->drupalPost('node/1/qforms-result/1/delete', array(), t('Delete'));
    $this->assertText(t('Submission has been deleted.'));

    $this->addData();

    // Test node delete.
    $this->drupalGet('node/1/delete');
    $this->assertText(t('Are you sure you want to delete') . ' Car survey' . '?');
    $this->drupalPost('node/1/delete', array(), t('Delete'));
    $this->assertText(t('Qform @title has been deleted.', array('@title' => 'Car survey')));

    // Test delete of submissions related to deleted node.
    $select = db_select('qforms_submission', 'ss');
    $select->addField('ss', 'nid');
    $select->condition('nid', 1);
    $rows = $select->execute()->fetchAll();
    $this->assert(empty($rows), t('All submissions of the deleted node has been deleted too'));

    $this->drupalLogout();
  }

  /**
   * Other user can only have permission to see qform, not to modify it.
   */
  public function testPermissions() {
    $this->drupalLogin($this->auth_user1);
    $this->addContent();
    $this->assertText(t('Edit'));
    $this->drupalGet('node/1');
    $this->assertText('View');
    $this->drupalLogout();

    // Test whether other user can edit content created by other user.
    $this->drupalLogin($this->auth_user2);
    $this->drupalGet('node/1');
    $this->assertNoText(t('Edit'));
    $this->drupalLogout();

    // This user doesn't have permission 'view and submit qform' and he shouldn't be able to see input fields.
    $not_auth_user = $this->drupalCreateUser(array('create qform content', 'edit own qform content', 'delete own qform content'));
    $this->drupalLogin($not_auth_user);
    $this->drupalGet('node/1');
    $passed = $this->assertNoText(t('Why do you like cars (briefly)?'));
    $passed = $passed && $this->assertNoField('qforms_textfield_6', t('Founded input text.'));
    $passed = $passed && $this->assertNoText(t('Briefly explain why do you like cars'));
    $this->assert($passed, t('User is not able to see first field of a type input text - OK'));
  }

  /**
   *  Test export to csv.
   */
  public function testExport() {
    //require_once '../qforms.pages_export.inc';
    module_load_include('inc', 'qforms', 'qforms.pages_export');

    $this->drupalLogin($this->auth_user1);

    $this->addContent();

    // Before submited data.
    $node = $this->drupalGetNodeByTitle(t('Car survey'));
    $exported_results = qforms_results_submissions_export_base($node);
    $messages = drupal_get_messages();
    $status = $messages['status'];
    $cur = current($status);
    $this->assertEqual(t('No submission results.'), $cur);

    // After data has been submited.
    $this->addData();
    $exported_results = qforms_results_submissions_export_base($node);
    $file_content = $exported_results['file_content'];
    $exported_header = 'Id,Time,"Submited by","Why do you like cars (detail)?","I like car because...","Favorite brand","Favorite color","Why do you like cars (briefly)?"';
    $exported_body_sufix = '"They are very useful since I can travel very quickly","I can travel quickly, I just like to drive, I can transfer weight","Toyota, Mercedes","Black, Gray","They are very useful"';

    $passed = ((substr_count($file_content, $exported_header) + substr_count($file_content, $exported_body_sufix)) < 2) ? FALSE : TRUE;
    $this->assert($passed, t("All visible data is exported"));
    $passed = (substr_count($file_content, 'Are you a driver?') + substr_count($file_content, '"They are very useful","') > 0) ? FALSE : TRUE;
    $this->assert($passed, t("Invisible data hasn't been exported"));
  }

  /**
   * Test whether other field is shown consistantly with qforms definition.
   */
  public function testOtherField() {
    $this->drupalLogin($this->auth_user1);

    $qform_def_no_other = 'a:7:{s:25:"qforms_element_2_textarea";a:9:{s:4:"type";s:8:"textarea";s:6:"delete";s:0:"";s:2:"id";s:25:"qforms_element_2_textarea";s:6:"weight";s:1:"2";s:5:"title";s:30:"Why do you like cars (detail)?";s:11:"description";s:28:"Explain why do you like cars";s:8:"required";i:0;s:7:"visible";i:1;s:4:"size";s:2:"60";}s:27:"qforms_element_3_checkboxes";a:22:{s:4:"type";s:10:"checkboxes";s:6:"delete";s:0:"";s:2:"id";s:27:"qforms_element_3_checkboxes";s:6:"weight";s:1:"3";s:5:"title";s:21:"I like car because...";s:11:"description";s:28:"Reasons why do you like cars";s:8:"required";i:0;s:7:"visible";i:1;s:17:"options_1_default";i:1;s:12:"options_1_id";i:1;s:22:"options_1_option_value";s:20:"I can travel quickly";s:14:"last_option_id";i:1;s:17:"options_3_default";i:0;s:12:"options_3_id";i:3;s:22:"options_3_option_value";s:20:"I have air condition";s:17:"options_4_default";i:0;s:12:"options_4_id";i:4;s:22:"options_4_option_value";s:20:"I just like to drive";s:17:"options_5_default";i:0;s:12:"options_5_id";i:5;s:22:"options_5_option_value";s:19:"I have full comfort";s:5:"other";i:0;}s:23:"qforms_element_4_radios";a:25:{s:4:"type";s:6:"radios";s:6:"delete";s:0:"";s:2:"id";s:23:"qforms_element_4_radios";s:6:"weight";s:1:"4";s:5:"title";s:14:"Favorite brand";s:11:"description";s:19:"Your favorite brand";s:8:"required";i:1;s:7:"visible";i:1;s:17:"options_1_default";i:0;s:12:"options_1_id";i:1;s:22:"options_1_option_value";s:6:"Toyota";s:14:"last_option_id";i:1;s:17:"options_2_default";i:0;s:12:"options_2_id";i:2;s:22:"options_2_option_value";s:2:"VW";s:17:"options_3_default";i:0;s:12:"options_3_id";i:3;s:22:"options_3_option_value";s:4:"Ford";s:17:"options_4_default";i:0;s:12:"options_4_id";i:4;s:22:"options_4_option_value";s:4:"Opel";s:17:"options_5_default";i:0;s:12:"options_5_id";i:5;s:22:"options_5_option_value";s:3:"BMW";s:5:"other";i:0;}s:23:"qforms_element_5_select";a:26:{s:4:"type";s:6:"select";s:6:"delete";s:0:"";s:2:"id";s:23:"qforms_element_5_select";s:6:"weight";s:1:"5";s:5:"title";s:14:"Favorite color";s:11:"description";s:19:"Your favorite color";s:8:"required";i:0;s:7:"visible";i:1;s:17:"options_1_default";i:0;s:12:"options_1_id";i:1;s:22:"options_1_option_value";s:5:"White";s:14:"last_option_id";i:1;s:17:"options_2_default";i:0;s:12:"options_2_id";i:2;s:22:"options_2_option_value";s:4:"Blue";s:17:"options_3_default";i:0;s:12:"options_3_id";i:3;s:22:"options_3_option_value";s:5:"Green";s:17:"options_4_default";i:0;s:12:"options_4_id";i:4;s:22:"options_4_option_value";s:3:"Red";s:17:"options_5_default";i:0;s:12:"options_5_id";i:5;s:22:"options_5_option_value";s:5:"Black";s:8:"multiple";i:0;s:5:"other";i:0;}s:26:"qforms_element_6_textfield";a:9:{s:4:"type";s:9:"textfield";s:6:"delete";s:0:"";s:2:"id";s:26:"qforms_element_6_textfield";s:6:"weight";s:1:"6";s:5:"title";s:31:"Why do you like cars (briefly)?";s:11:"description";s:36:"Briefly explain why do you like cars";s:8:"required";i:1;s:7:"visible";i:1;s:4:"size";s:2:"60";}s:26:"qforms_element_7_textfield";a:9:{s:4:"type";s:9:"textfield";s:6:"delete";s:0:"";s:2:"id";s:26:"qforms_element_7_textfield";s:6:"weight";s:1:"7";s:5:"title";s:17:"Are you a driver?";s:11:"description";s:29:"Do you have a driver licence?";s:8:"required";i:0;s:7:"visible";i:0;s:4:"size";s:2:"20";}s:22:"qforms_last_element_id";i:7;}';

    $this->addContent();

    $this->drupalGet('node/1');
    $this->assertRaw('<label for="edit-qforms-element-3-checkboxes-qforms-element-3-checkboxes-other">Other </label>');
    $this->assertField('edit-qforms-element-3-checkboxes-qforms-element-3-checkboxes-other', 'Other field for checkbox is OK');
    $this->assertRaw('<label for="edit-qforms-element-4-radios-other">Other </label>');
    $this->assertField('edit-qforms-element-4-radios-other', 'Other field for radios is OK');
    $this->assertRaw('<label for="edit-qforms-element-5-select-other">Other </label>');
    $this->assertField('edit-qforms-element-5-select-other', 'Other field for select is OK');

    $this->addContent($qform_def_no_other, 2);
    $this->drupalGet('node/2');
    $this->assertNoRaw('<label for="edit-qforms-element-3-checkboxes-qforms-element-3-checkboxes-other">Other </label>');
    $this->assertNoField('edit-qforms-element-3-checkboxes-qforms-element-3-checkboxes-other', 'Other field for checkbox is OK');
    $this->assertNoRaw('<label for="edit-qforms-element-4-radios-other">Other </label>');
    $this->assertNoField('edit-qforms-element-4-radios-other', 'Other field for radios is OK');
    $this->assertNoRaw('<label for="edit-qforms-element-5-select-other">Other </label>');
    $this->assertNoField('edit-qforms-element-5-select-other', 'Other field for select is OK');
  }


  public function testPreview() {
    $this->drupalLogin($this->auth_user1);
    $this->addContent();

    $edit = unserialize($this->qform_def);
    $edit = $this->definitionToArrayForSubmit($edit);
    $edit['title'] = t('Car survey');

    $this->drupalPost('node/1/edit', $edit, t('Preview'));
    $this->qformsAssertUserForm();
  }
    
  /**
   *  Add qform content/node.
   */
  public function addContent($qform_def = NULL, $node_id = NULL) {
    $edit['title'] = t('Car survey');
    if ($qform_def == NULL) {
      $qform_def = $this->qform_def;
    }
    if ($node_id == NULL) {
      $node_id = 1;
    }
    $this->drupalPost('node/add/qform', $edit, t('Save'));
    $this->assertText(t('Qform @title has been created.', array('@title' => $edit['title'])));
    
    qforms_db_delete_form($node_id);
    qforms_db_save_form($node_id, $qform_def, '');
  }

  public function definitionToArrayForSubmit($definitions) {
    foreach ($definitions as $definition) {
      if (is_array($definition)) {
        $id = $definition['id'];
        $element[$id . '_title'] = $definition['title'];
        $element[$id . '_description'] = $definition['description'];
        $element[$id . '_required'] = $definition['required'];
        $element[$id . '_weight'] = $definition['weight'];
        $element[$id . '_visible'] = ($definition['visible']) ? TRUE : FALSE;
        if (isset($definition['size'])) {
          $element[$id . '_size'] = $definition['size'];
        }
        if (isset($definition['other'])) {
          $element[$id . '_other'] = $definition['other'];
        }

        foreach ($definition as $key => $value) {
          if (substr_count($key, 'options_') > 0) {
            $id_core = substr($key, strlen('options_'), 1);
            if ($key == 'options_' . $id_core . '_option_value') {
              $element[$id . '_options_' . $id_core . '_option_value'] = $definition['options_' . $id_core . '_option_value'];
            }
          }
        }
      }
    }
    return $element;
  }

  public function qformsAssertUserForm() {
    // Assert the whole field - its label, actual input field and its description.
    $this->assertText(t('Car survey'), 'Title is OK.');
    $passed = $this->assertText(t('Why do you like cars (briefly)?'));
    $passed = $passed && $this->assertField('edit-qforms-element-6-textfield', t('Founded input text.'));
    $passed = $passed && $this->assertText(t('Briefly explain why do you like cars'));
    $this->assert($passed, t('First field of a type input text is OK'));
    $passed = $this->assertText(t('Why do you like cars (detail)?'));
    $passed = $passed && $this->assertField('edit-qforms-element-2-textarea', t('Founded input textarea.'));
    $passed = $passed && $this->assertText(t('Explain why do you like cars'));
    $this->assert($passed, t('Second field of a type textarea is OK'));
    $passed = $this->assertText(t('I like car because...'));

    // Test option's default value (this field should be checked by default).
    $passed = $passed && $this->assertFieldChecked('edit-qforms-element-3-checkboxes-i-can-travel-quickly',
      t('Founded input checkboxes and this option is checked by default'));
    $passed = $passed && $this->assertNoFieldChecked('edit-qforms-element-3-checkboxes-i-have-air-condition',
      t('Founded input checkboxes and this option is not checked by default'));

    $passed = $passed && $this->assertText(t('Reasons why do you like cars'));
    $this->assert($passed, t('Third field of a type input checkboxes is OK'));
    $passed = $this->assertText(t('Favorite brand'));
    $passed = $passed && $this->assertField('qforms_element_4_radios', t('Founded input radios.'));
    $passed = $passed && $this->assertText(t('Your favorite brand'));
    $this->assert($passed, t('Fourth field of a type input radios is OK'));
    $passed = $this->assertText(t('Favorite color'));
    $passed = $passed && $this->assertField('qforms_element_5_select', t('Founded input select.'));
    $passed = $passed && $this->assertText(t('Your favorite color'));
    $this->assert($passed, t('Fifth field of a type input select is OK'));

    // Testing visibility of the field (this field isn't visible).
    $passed = $this->assertNoText(t('Do you have a driver licence?'));
    $this->assert($passed, t('Visibility is OK'));
  }

  /**
   *  Popoulate form with data.
   */
  public function addData($url = 'node/1', $button = 'Submit') {
    $this->drupalGet($url);
    $datas['qforms_element_6_textfield'] = t('They are very useful');
    $datas['qforms_element_2_textarea'] = t('They are very useful since I can travel very quickly');
    $datas['qforms_element_3_checkboxes[I just like to drive]'] = t('I just like to drive');
    $datas['qforms_element_3_checkboxes[qforms_element_3_checkboxes_other]'] = t('I can transfer weight');
    $datas['qforms_element_4_radios'] = t('Toyota');
    $datas['qforms_element_4_radios_other'] = t('Mercedes');
    $datas['qforms_element_5_select'] = t('Black');
    $datas['qforms_element_5_select_other'] = t('Gray');

    $this->drupalPost($url, $datas, t($button));
    $this->assertText(t('Submission results'));
  }
}
