You are here

public function FillPdfMergeTestCase::testPdfMerging in FillPDF 7

Test PDF merging.

Throws

\FieldException

File

tests/FillPdfMergeTestCase.test, line 58

Class

FillPdfMergeTestCase
Tests that PDF population and token replacement works.

Code

public function testPdfMerging() {
  features_revert_module('fillpdf_test_webform');

  // Can we get to the Webform we created?
  $webform = webform_features_machine_name_load('fillpdf_test_webform');
  $this
    ->assertTrue(property_exists($webform, 'nid'), 'Webform properly loaded from Features.');
  $this
    ->createImageField('field_test_image', 'node', 'article');
  $files = $this
    ->drupalGetTestFiles('image');
  $image = reset($files);

  // Clear cache and grant more permissions to ensure ability to create nodes.
  $existing_roles = array_keys($this->privilegedUser->roles);
  $granted_rid = end($existing_roles);
  user_role_change_permissions($granted_rid, array(
    'create webform content' => TRUE,
    'create article content' => TRUE,
  ));
  $this->testNode = node_load($this
    ->createImageFieldEntity($image, 'field_test_image', 'node', 'article'));

  // Test with a node.
  $this
    ->uploadTestPdf();
  $fillpdf_form = fillpdf_load($this
    ->getLatestFillPdfForm());

  // Get the field definitions for the form that was created and configure
  // them.
  $fid = $fillpdf_form->fid;
  $fields = fillpdf_get_fields($fid);
  $this
    ->mapFillPdfFieldsToEntityFields('node', $fields, $fid);

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $fid,
      'nid' => $this->testNode->nid,
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $merge_result = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($merge_result['fields']['TextField'], $this->testNode->title, 'PDF is populated with the title of the node.');

  // *******************************
  // *******************************
  // Ensure entity defaults don't overpower legacy nids in links or
  // fillpdf_merge_pdf() calls.
  // *******************************
  // *******************************
  $default_nid_test_node = node_load($this
    ->createImageFieldEntity($image, 'field_test_image', 'node', 'article'));

  // Test with a node.
  $this
    ->uploadTestPdf();
  $fillpdf_form_default = fillpdf_load($this
    ->getLatestFillPdfForm());
  $this
    ->drupalPost("admin/structure/fillpdf/{$fillpdf_form_default->fid}", array(
    'default_nid' => $default_nid_test_node->nid,
  ), t('Update'));

  // Get the field definitions for the form that was created and configure
  // them.
  $fid = $fillpdf_form_default->fid;
  $fields = fillpdf_get_fields($fid);
  $this
    ->mapFillPdfFieldsToEntityFields('node', $fields, $fillpdf_form_default->fid);

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $fillpdf_form_default->fid,
      'nid' => $this->testNode->nid,
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $merge_result = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($merge_result['fields']['TextField'], $this->testNode->title, 'Regression test: PDF is populated with the title of the correct node, not the default.');

  // These tests cover the official (and some unofficial) ways of building
  // FillPDF Links for entities. Official: entity_id, entity_ids, entity_type
  // + entity_id. Unofficial: entity (synonym for entity_id), entities
  // (synonym for entity_ids). It doesn't test entity_type + entity, but that
  // should work too. It's not officially supported, though. It's just that
  // the contributed patch already had those working, and there was no good
  // reason to take them out and make it harder for people to update their
  // version of FillPDF later.
  $this->testEntity = node_load($this
    ->createImageFieldEntity($image, 'field_test_image', 'node', 'article'));

  // Test with a node.
  $this
    ->uploadTestPdf();
  $fillpdf_form_entity = fillpdf_load($this
    ->getLatestFillPdfForm());

  // Get the field definitions for the form that was created and configure
  // them.
  $entity_fid = $fillpdf_form_entity->fid;
  $entity_fields = fillpdf_get_fields($entity_fid);
  $this
    ->mapFillPdfFieldsToEntityFields('node', $entity_fields, $entity_fid);

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
      'entity_id' => $this->testEntity->nid,
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $entity_merge_result_1 = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($entity_merge_result_1['fields']['TextField'], $this->testEntity->title, 'PDF is populated with the title of the node (via entity tokens
      and single-entity format).');

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
      'entity' => "node:{$this->testEntity->nid}",
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $entity_merge_result_2 = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($entity_merge_result_2['fields']['TextField'], $this->testEntity->title, 'PDF is populated with the title of the node (via entity tokens
      and alternative single-entity format).');
  $this
    ->createImageField('field_term_image', 'taxonomy_term', 'tags');
  $term_image = file_save($image);

  // Test an actual entity token (taxonomy terms).
  $tid = $this
    ->createImageFieldEntity($term_image, 'field_term_image', 'taxonomy_term', 'tags', 'Test term');
  $test_term = taxonomy_term_load($tid);

  // Re-map the PDF fields so that the following tests will work.
  $this
    ->mapFillPdfFieldsToEntityFields('taxonomy_term', $entity_fields, $entity_fid);

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
      'entity_ids' => array(
        "taxonomy_term:{$test_term->tid}",
      ),
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $entity_merge_result_3 = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($entity_merge_result_3['fields']['TextField'], $test_term->name, 'PDF is populated with the title of the taxonomy term.');
  $field_term_image = field_get_items('taxonomy_term', $test_term, 'field_term_image');
  $term_file = file_load($field_term_image[0]['fid']);
  $this
    ->assertEqual($entity_merge_result_3['images']['ImageField']['data'], base64_encode(file_get_contents($term_file->uri)), '(Entity mode) Encoded image matches known image.');
  $path_info = pathinfo($term_file->uri);
  $expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
  $this
    ->assertEqual($entity_merge_result_3['images']['ImageField']['filenamehash'], $expected_file_hash, '(Entity mode) Hashed filename matches known hash.');
  $this
    ->assertEqual($entity_merge_result_3['fields']['ImageField'], '{image}' . drupal_realpath($term_file->uri), '(Entity mode) URI in metadata matches expected URI.');

  // Clean up, since we're reusing these variables again later in the same
  // test. They weren't worth renaming.
  unset($path_info, $expected_file_hash);

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
      'entities' => array(
        "taxonomy_term:{$test_term->tid}",
      ),
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $entity_merge_result_4 = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($entity_merge_result_4['fields']['TextField'], $test_term->name, 'PDF is populated with the title of the taxonomy term.');

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
      'entity_type' => 'taxonomy_term',
      'entity_id' => $test_term->tid,
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $entity_merge_result_5 = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($entity_merge_result_5['fields']['TextField'], $test_term->name, 'PDF is populated with the title of the taxonomy term (via
      simplified format).');

  // Test filename title generation. Configure it, merge the PDF without
  // handling, and then save it as a file and check the name.
  db_update('fillpdf_forms')
    ->fields(array(
    'destination_path' => 'output',
    'title' => 'Token_[term:name]_title',
    'destination_redirect' => 1,
  ))
    ->condition('fid', $entity_fid)
    ->execute();
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
      'entity' => "taxonomy_term:{$test_term->tid}",
    ),
  ));
  $where_are_we = $this
    ->getUrl();
  $path_parts = explode('/', parse_url($where_are_we, PHP_URL_PATH));
  $filename = end($path_parts);
  if (empty($filename)) {

    // Wait, are we the d.o. testbot? Who else turns off clean URLs?
    // Alright, then; try the query string instead.
    $raw_query = parse_url($where_are_we, PHP_URL_QUERY);
    parse_str($raw_query, $parse_query);
    if (isset($parse_query['q'])) {
      $query_parts = explode('/', $parse_query['q']);
      $filename = end($query_parts);
    }
  }
  $expected_filename = 'Token_Test_term_title.pdf';
  $args = array(
    '@actual' => $filename,
    '@expected' => $expected_filename,
    '@url' => $where_are_we,
  );
  $this
    ->assertEqual($expected_filename, $filename, t('Filename of generated file (@actual) matches specified entity token pattern (@expected). Current page URL: @url', $args));

  // Test that node access via entity access works.
  // Make a basic page.
  $entity_access_test_node = new stdClass();
  $entity_access_test_node->type = 'page';
  $entity_access_test_node->title = t('Entity access test');
  $entity_access_test_node->field_body = array(
    LANGUAGE_NONE => array(
      0 => array(
        'value' => 'This is test text.',
      ),
    ),
  );
  $entity_access_test_node->uid = 1;
  node_save($entity_access_test_node);

  // Upload a fresh PDF, since we changed some settings on the other one.
  $this
    ->uploadTestPdf();
  $entity_access_pdf = fillpdf_load($this
    ->getLatestFillPdfForm());

  // Get the field definitions for the form that was created and configure
  // them.
  $entity_access_fid = $entity_access_pdf->fid;
  $entity_access_fields = fillpdf_get_fields($entity_access_fid);
  $this
    ->mapFillPdfFieldsToEntityFields('node', $entity_access_fields, $entity_access_fid);
  $this
    ->drupalLogin($this->nonPrivilegedUser);
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_access_fid,
      'entity' => "node:{$entity_access_test_node->nid}",
    ),
  ));
  $this
    ->assertResponse(403, 'User must have access to base entity to fill in PDF.');

  // Restore privileged user.
  $this
    ->drupalLogin($this->privilegedUser);

  // Test classic default NID handling (turn off the Entity API module).
  // It's enough to disable entity_token without the parent entity module,
  // since we always check for entity_token specifically.
  module_disable(array(
    'entity_token',
  ));
  $this
    ->drupalPost("admin/structure/fillpdf/{$entity_access_fid}", array(
    'default_nid' => $entity_access_test_node->nid,
  ), t('Update'));

  // Ensure default_entity_type is NULL in the database, as this is a
  // regression to make sure old-style default_nid isn't broken.
  db_update('fillpdf_forms')
    ->condition('fid', $entity_access_fid)
    ->fields(array(
    'default_entity_type' => NULL,
  ))
    ->execute();
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_access_fid,
    ),
  ));
  $default_nid_merge_result = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual('Entity access test', $default_nid_merge_result['fields']['TextField'], 'Configured node properly used as default when no parameters specified.');

  // Re-enable Entity Tokens.
  module_enable(array(
    'entity_token',
  ));

  // Test default entity type/entity ID. We use the browser to set these to
  // ensure the fields are there.
  $this
    ->drupalPost("admin/structure/fillpdf/{$entity_fid}", array(
    'default_nid' => $test_term->tid,
    'default_entity_type' => 'taxonomy_term',
  ), t('Update'));
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $entity_fid,
    ),
  ));
  $default_entity_merge_result = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual('Test term', $default_entity_merge_result['fields']['TextField'], 'Test term set as default entity properly used when no parameters specified.');
  $field_test_image = field_get_items('node', $this->testNode, 'field_test_image');
  $node_file = file_load($field_test_image[0]['fid']);
  $this
    ->assertEqual($merge_result['images']['ImageField']['data'], base64_encode(file_get_contents($node_file->uri)), 'Encoded image matches known image.');
  $path_info = pathinfo($node_file->uri);
  $expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
  $this
    ->assertEqual($merge_result['images']['ImageField']['filenamehash'], $expected_file_hash, 'Hashed filename matches known hash.');
  $this
    ->assertEqual($merge_result['fields']['ImageField'], '{image}' . drupal_realpath($node_file->uri), 'URI in metadata matches expected URI.');

  // Test the legacy [stamp] pseudo-token.
  $legacy_fields = fillpdf_get_fields($fid);
  foreach ($legacy_fields as $legacy_pdf_key => $legacy_field) {
    switch ($legacy_pdf_key) {
      case 'ImageField':
        $legacy_field['value'] = '[stamp:field_test_image]';
        break;
    }
    fillpdf_fields_create_update($fid, $legacy_pdf_key, $legacy_field, TRUE);
  }

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $fid,
      'nid' => $this->testNode->nid,
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $legacy_merge_result = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertTrue($legacy_merge_result['flatten'], 'PDF is set to be flattened.');
  $this
    ->assertEqual($legacy_merge_result['images']['ImageField']['data'], base64_encode(file_get_contents($node_file->uri)), 'Legacy: Encoded image matches known image.');
  $this
    ->assertEqual($legacy_merge_result['images']['ImageField']['filenamehash'], $expected_file_hash, 'Legacy: Hashed filename matches known hash.');
  $this
    ->assertEqual($legacy_merge_result['fields']['ImageField'], '{image}' . drupal_realpath($node_file->uri), 'Legacy: URI in metadata matches expected URI.');

  // Test Webform image filling.
  $this
    ->uploadTestPdf();
  $fillpdf_form2 = fillpdf_load($this
    ->getLatestFillPdfForm());

  // Create a test submission for our test Webform.
  $this
    ->drupalPost("node/{$webform->nid}", array(
    'files[submitted_image_field]' => drupal_realpath($image->uri),
  ), t('Submit'));

  // Get the submission.
  $url_parts = drupal_parse_url($this
    ->getUrl());
  module_load_include('inc', 'webform', 'includes/webform.submissions');
  $submission = webform_get_submission($webform->nid, $url_parts['query']['sid']);

  // Get the field definitions for the form that was created and configure
  // them.
  $wf_fields = fillpdf_get_fields($fillpdf_form2->fid);
  foreach ($wf_fields as $wf_pdf_key => $wf_field) {
    switch ($wf_pdf_key) {
      case 'ImageField':
        $wf_field['value'] = '[submission:values:image_field]';
        break;
      case 'TextField':
        $wf_field['value'] = '[node:title]';
        break;
    }
    fillpdf_fields_create_update($fillpdf_form2->fid, $wf_pdf_key, $wf_field, TRUE);
  }

  // Hit the FillPDF URL, check the results from the test fill method.
  $this
    ->drupalGet('fillpdf', array(
    'query' => array(
      'fid' => $fillpdf_form2->fid,
      'webforms[0][nid]' => $webform->nid,
      'webforms[0][sid]' => $submission->sid,
    ),
  ));

  // We don't actually care about downloading the fake PDF. We just want to
  // check what happened in the backend.
  $merge_result = variable_get('fillpdf_test_last_merge_metadata');
  $this
    ->assertEqual($merge_result['fields']['TextField'], $webform->title, 'PDF is populated with the title of the Webform node.');

  // Find the image_field component.
  $image_field_cid = NULL;
  foreach ($webform->webform['components'] as $cid => $component) {
    if ($component['form_key'] === 'image_field') {
      $image_field_cid = $cid;
      break;
    }
  }
  $webform_file = file_load($submission->data[$image_field_cid][0]);
  $this
    ->assertEqual($merge_result['images']['ImageField']['data'], base64_encode(file_get_contents($webform_file->uri)), 'Encoded image matches known image.');
  $path_info = pathinfo($webform_file->uri);
  $expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
  $this
    ->assertEqual($merge_result['images']['ImageField']['filenamehash'], $expected_file_hash, 'Hashed filename matches known hash.');
  $this
    ->assertEqual($merge_result['fields']['ImageField'], '{image}' . drupal_realpath($webform_file->uri), 'URI in metadata matches expected URI.');
}