<?php
// $Id: filefield_paths.test,v 1.1.2.4 2009/06/17 22:53:38 deciphered Exp $

/**
 * @file
 * This file implements tests for FileField Paths.
 */

class FileFieldPathsTestCase extends DrupalWebTestCase {
  protected $admin_user;

  /**
   * Implementation of setUp().
   */
  function setUp($modules = array(), $permissions = array()) {
    $modules = array_merge($modules, array('filefield_paths', 'token'));
    call_user_func_array(array($this, 'parent::setUp'), $modules);

    // Create and login user
    $permissions = array_merge($permissions, array('administer content types', 'administer nodes'));
    $this->admin_user = $this->drupalCreateUser($permissions);
    $this->drupalLogin($this->admin_user);
  }

  function checkDependancy($module) {
    $result = db_fetch_object(db_query(
      "SELECT filename FROM {system} WHERE type = 'module' AND name = '%s'", $module
    ));

    if (is_object($result) && file_exists($result->filename)) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Upload a file to a node.
   *
   * Modified version of FileFieldTestCase::uploadNodeFile().
   */
  function uploadNodeFile($file, $field_name, $type) {
    $edit = array(
      'title' => $this->randomName(),
      'files['. $field_name .']' => realpath($file['path']),
      'body' => l(t('link'), file_directory_path() .'/'. $file['name'])
    );

    $type = str_replace('_', '-', $type);
    $this->drupalPost('node/add/' . $type, $edit, t('Save'));

    $matches = array();
    preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
    return isset($matches[1]) ? $matches[1] : FALSE;
  }

  function checkFileName($file, $node, $retroactive = FALSE) {
    $origfile = pathinfo($file['origname']);
    $filename = $node->title .'.'. $origfile['extension'];
    $message = t('Make sure filename has been processed.');

    if ($retroactive) {
      $filename = 'retroactive-'. $filename;
      $message = t('Make sure filename has been retroactively processed.');
    }

    $this->assertEqual($file['filename'], $filename, $message, 'FileField Paths');
  }

  function checkFilePath($file, $node, $retroactive = FALSE) {
    $filepath = file_directory_path() .'/node/'. $node->nid .'/'. $file['filename'];
    $message = t('Make sure filepath has been processed.');

    if ($retroactive) {
      $filename = $filepath = file_directory_path() .'/retroactive-node/'. $node->nid .'/'. $file['filename'];
      $message = t('Make sure filepath has been retroactively processed.');
    }

    $this->assertEqual($file['filepath'], $filepath, $message, 'FileField Paths');
  }

  function checkNodeBody($file, $retroactive = FALSE) {
    $this->assertPattern('|'. $file['filepath'] .'|', t('Make sure filepath in Node Body has been processed.'), 'FileField Paths');
  }

  function setFileFieldPathsSettings($field, $edit = array(), $retroactive = FALSE) {
    $edit['ffp_'. $field .'[file_path]'] = 'node/[nid]';
    $edit['ffp_'. $field .'[file_name]'] = '[title-raw].[filefield-extension-original]';

    if ($retroactive) {
      $edit['ffp_'. $field .'[file_path]'] = 'retroactive-'. $edit['ffp_'. $field .'[file_path]'];
      $edit['ffp_'. $field .'[file_name]'] = 'retroactive-'. $edit['ffp_'. $field .'[file_name]'];
      $edit['ffp_'. $field .'[retroactive_update]'] = 1;
    }
    return $edit;
  }
}

/**
 * Tests Comment Upload module integration.
 */
if (FileFieldPathsTestCase::checkDependancy('comment_upload')) {
  class FileFieldPathsCommentUploadTestCase extends FileFieldPathsTestCase {
    /**
     * Implementation of getInfo().
     */
    public static function getInfo() {
      return array(
        'name' => t('Comment Upload integration'),
        'description' => t('Test FileField Paths integration with the Comment Upload module.'),
        'group' => t('FileField Paths'),
      );
    }

    /**
     * Implementation of setUp().
     */
    function setUp() {
      parent::setUp(
        array('comment_upload', 'comment', 'upload'), // Modules
        array('upload files to comments', 'view files uploaded to comments') // Permissions
      );
    }

    /**
     * Test file upload.
     */
    function testUploadFile() {
      // Create content type.
      $type = $this->drupalCreateContentType();

      // Set Comment Upload and FileField Paths settings.
      $edit = array(
        'comment_preview' => 0,
        'comment_upload' => 1,
      );
      $edit = $this->setFileFieldPathsSettings('comment_upload', $edit);
      $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name), $edit, t('Save content type'));

      // Create Node.
      $settings = array(
        'type' => $type->name,
      );
      $node = $this->drupalCreateNode($settings);
      $this->node_id = $node->nid;

      // Create Comment with uploaded file.
      $test_files = $this->drupalGetTestFiles('text');
      $edit = array(
        'comment' => $this->randomName(32),
        'files[upload]' => $test_files[0]->filename,
      );
      $this->drupalPost('comment/reply/'. $node->nid, $edit, t('Save'));

      // Get Comment ID.
      $matches = array();
      preg_match('/node\/[0-9]+\#comment\-([0-9]+)/', $this->getUrl(), $matches);
      $cid = $matches[1];

      // Load uploaded file.
      $comment_files = comment_upload_load_files($cid);

      // Check file has been processed correctly.
      $this->checkFileName($comment_files[1], $node);
      $this->checkFilePath($comment_files[1], $node);

      // Change FileField Paths settings.
      $edit = $this->setFileFieldPathsSettings('comment_upload', array(), TRUE);
      $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name), $edit, t('Save content type'));

      // Load uploaded file.
      $comment_files = comment_upload_load_files($cid);

      // Check file has been retroactively updated correctly.
      $this->checkFileName($comment_files[1], $node, TRUE);
      $this->checkFilePath($comment_files[1], $node, TRUE);
    }
  }
}

/**
 * Tests FileField module integration.
 */
if (FileFieldPathsTestCase::checkDependancy('filefield')) {
  class FileFieldPathsFileFieldTestCase extends FileFieldTestCase {
    /**
     * Implementation of getInfo().
     */
    public static function getInfo() {
      return array(
        'name' => t('FileField integration'),
        'description' => t('Test FileField Paths integration with the FileField module.'),
        'group' => t('FileField Paths'),
      );
    }

    /**
     * Implementation of setUp().
     */
    function setUp() {
      parent::setUp('filefield_paths');
    }

    /**
     * Test file upload.
     */
    function testUploadFile() {
      // Create content type.
      $type = $this->drupalCreateContentType();

      // Create CCK FileField.
      $field_name = 'field_'. drupal_strtolower($this->randomName());
      $field = $this->createFileField($field_name, $type->name);

      // Set FileField Paths settings.
      $edit = FileFieldPathsTestCase::setFileFieldPathsSettings($field_name);
      $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name) .'/fields/'. $field_name, $edit, t('Save field settings'));

      // Upload test file.
      $test_file = $this->getTestFile('text');
      $nid = FileFieldPathsTestCase::uploadNodeFile(array('path' => $test_file->filepath, 'name' => $test_file->filename), $field_name .'_0', $type->name);

      // Load uploaded file.
      $node = node_load($nid, NULL, TRUE);
      $node_file = $node->{$field_name}[0];

      // Check file has been processed correctly.
      FileFieldPathsTestCase::checkFileName($node_file, $node);
      FileFieldPathsTestCase::checkFilePath($node_file, $node);
      FileFieldPathsTestCase::checkNodeBody($node_file);

      // Change FileField Paths settings.
      $edit = FileFieldPathsTestCase::setFileFieldPathsSettings($field_name, array(), TRUE);
      $test = $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name) .'/fields/'. $field_name, $edit, t('Save field settings'));

      // Load uploaded file.
      $node = node_load($nid, NULL, TRUE);
      $node_file = $node->{$field_name}[0];

      // Check file has been retroactively updated correctly.
      FileFieldPathsTestCase::checkFileName($node_file, $node, TRUE);
      FileFieldPathsTestCase::checkFilePath($node_file, $node, TRUE);
    }
  }
}

/**
 * Tests ImageField module integration.
 */
if (FileFieldPathsTestCase::checkDependancy('filefield') && FileFieldPathsTestCase::checkDependancy('imagefield')) {
  class FileFieldPathsImageFieldTestCase extends FileFieldTestCase {
    /**
     * Implementation of getInfo().
     */
    public static function getInfo() {
      return array(
        'name' => t('ImageField integration'),
        'description' => t('Test FileField Paths integration with the ImageField module.'),
        'group' => t('FileField Paths'),
      );
    }

    /**
     * Implementation of setUp().
     */
    function setUp() {
      parent::setUp('imagefield', 'filefield_paths');
    }

    /**
     * Test file upload.
     */
    function testUploadImage() {
      // Create content type.
      $type = $this->drupalCreateContentType();

      // Create CCK ImageField.
      $field_name = 'field_'. drupal_strtolower($this->randomName());
      ImageFieldTestCase::createImageField($field_name, $type->name);

      // Set FileField Paths settings.
      $edit = FileFieldPathsTestCase::setFileFieldPathsSettings($field_name);
      $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name) .'/fields/'. $field_name, $edit, t('Save field settings'));

      // Upload test file.
      $test_file = $this->getTestFile('image');
      $nid = FileFieldPathsTestCase::uploadNodeFile(array('path' => $test_file->filepath, 'name' => $test_file->filename), $field_name .'_0', $type->name);

      // Load uploaded file.
      $node = node_load($nid, NULL, TRUE);
      $node_file = $node->{$field_name}[0];

      // Check file has been processed correctly.
      FileFieldPathsTestCase::checkFileName($node_file, $node);
      FileFieldPathsTestCase::checkFilePath($node_file, $node);
      FileFieldPathsTestCase::checkNodeBody($node_file);

      // Check old thumbnail has been deleted.
      $this->assertFileNotExists(imagefield_file_admin_thumb_path($test_file), t('Make sure old thumbnail has been deleted.'));

      // Check new thumbnail has been created.
      $this->drupalGet('node/'. $nid .'/edit');
      $this->assertFileNotExists(imagefield_file_admin_thumb_path($node_file['filepath']), t('Make sure new thumbnail has been created.'));

      // Change FileField Paths settings.
      $edit = FileFieldPathsTestCase::setFileFieldPathsSettings($field_name, array(), TRUE);
      $test = $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name) .'/fields/'. $field_name, $edit, t('Save field settings'));

      // Load uploaded file.
      $node = node_load($nid, NULL, TRUE);
      $node_file = $node->{$field_name}[0];

      // Check file has been retroactively updated correctly.
      FileFieldPathsTestCase::checkFileName($node_file, $node, TRUE);
      FileFieldPathsTestCase::checkFilePath($node_file, $node, TRUE);
    }
  }
}

/**
 * Tests Drupal core Upload module integration.
 */
class FileFieldPathsUploadTestCase extends FileFieldPathsTestCase {
  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => t('Upload integration'),
      'description' => t('Test FileField Paths integration with the Upload module.'),
      'group' => t('FileField Paths'),
    );
  }

  /**
   * Implementation of setUp().
   */
  function setUp() {
    parent::setUp(
      array('upload'), // Modules
      array('upload files') // Permissions
    );
  }

  /**
   * Test file upload.
   */
  function testUploadFile() {
    // Create content type.
    $type = $this->drupalCreateContentType();

    // Set FileField Paths settings.
    $edit = $this->setFileFieldPathsSettings('upload');
    $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name), $edit, t('Save content type'));

    // Create Node with uploaded file.
    $test_files = $this->drupalGetTestFiles('text');
    $nid = $this->uploadNodeFile(array('path' => $test_files[0]->filename, 'name' => $test_files[0]->basename), 'upload', $type->name);

    // Load uploaded file.
    $node = node_load($nid, NULL, TRUE);
    $node_file = $node->files[1];

    // Check file has been processed correctly.
    $this->checkFileName((array) $node_file, $node);
    $this->checkFilePath((array) $node_file, $node);
    $this->checkNodeBody((array) $node_file);

    // Change FileField Paths settings.
    $edit = FileFieldPathsTestCase::setFileFieldPathsSettings('upload', array(), TRUE);
    $this->drupalPost('admin/content/node-type/'. str_replace('_', '-', $type->name), $edit, t('Save content type'));

    // Load uploaded file.
    $node = node_load($nid, NULL, TRUE);
    $node_file = $node->files[1];

    // Check file has been retroactively updated correctly.
    $this->checkFileName((array) $node_file, $node, TRUE);
    $this->checkFilePath((array) $node_file, $node, TRUE);
  }
}
