<?php

/**
 * @file
 * Tests for FeedsXPathParserXML.inc.
 */

/**
 * Test single feeds.
 */
class FeedsXPathParserXMLTestCase extends FeedsXPathParserWebTestCase {

  /**
   * Describe this test.
   */
  public static function getInfo() {
    return array(
      'name' => 'XML Parser',
      'description' => 'Regression tests for Feeds XPath XML parser.',
      'group' => 'Feeds XPath Parser',
    );
  }

  /**
   * Run tests.
   */
  public function test() {
    $this->createImporterConfiguration('XPathXML', 'xpath_xml');

    $this->setPlugin('xpath_xml', 'FeedsXPathParserXML');
    $importer_url = $this->feeds_base . '/xpath_xml/settings/FeedsXPathParserXML';
    // Check help message.
    $this->drupalGet($importer_url);
    $this->assertText('No XPath mappings are defined.');

    $this->addMappings('xpath_xml', array(
      0 => array(
        'source' => 'xpathparser:0',
        'target' => 'title',
        'unique' => FALSE,
      ),
      1 => array(
        'source' => 'xpathparser:1',
        'target' => 'guid',
        'unique' => TRUE,
      ),
      2 => array(
        'source' => 'xpathparser:2',
        'target' => 'body',
      ),
    ));
    // Set importer default settings.
    $edit = array(
      'xpath[context]' => '//entry',
      'xpath[sources][xpathparser:0]' => 'title',
      'xpath[sources][xpathparser:1]' => 'id',
      'xpath[sources][xpathparser:2]' => 'id',
    );
    $this->postAndCheck($importer_url, $edit, 'Save', 'Your changes have been saved.');

    // Test import.
    $path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds_xpathparser') . '/tests/feeds_xpathparser/';
    // We use an atom feed so that we can test that default namespaces are being
    // applied appropriately.
    $nid = $this->createFeedNode('xpath_xml', $path . 'sample_atom_feed.xml', 'Testing XPath XML Parser');
    $feed_node_edit_url = 'node/' . $nid . '/edit';
    $this->assertText('Created 3 nodes');

    // Import again, this verifies url field was mapped correctly.
    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
    $this->assertText('There are no new nodes');

    // Assert accuracy of aggregated content. I find humor in using our own
    // issue queue to run tests against.
    $this->drupalGet('node');
    $this->assertText('Atom-Powered Robots Run Amok');
    $this->assertText('My dog Jack is the best.');
    $this->assertText('Physics is cool.');

    // Test debugging.
    $edit = array(
      'feeds[FeedsXPathParserXML][xpath][exp][debug][xpathparser:0]' => TRUE,
    );
    $this->postAndCheck($feed_node_edit_url, $edit, 'Save', 'Basic page Testing XPath XML Parser has been updated.');
    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
    $this->assertText('&lt;title&gt;Atom-Powered Robots Run Amok&lt;/title&gt;');
    $this->assertText('&lt;title&gt;My dog Jack is the best.&lt;/title&gt;');
    $this->assertText('&lt;title&gt;Physics is cool.&lt;/title&gt;');
    $this->assertText('There are no new nodes.');

    // Turn debugging off.
    $edit = array(
      'feeds[FeedsXPathParserXML][xpath][exp][debug][xpathparser:0]' => FALSE,
    );
    $this->postAndCheck($feed_node_edit_url, $edit, 'Save', 'Basic page Testing XPath XML Parser has been updated.');

    // Check if update existing nodes works.
    $this->setSettings('xpath_xml', 'FeedsNodeProcessor', array('update_existing' => 2));
    $edit = array(
      'feeds[FeedsHTTPFetcher][source]' => $path . 'sample_atom_feed_updated.xml',
    );
    $this->postAndCheck($feed_node_edit_url, $edit, 'Save', 'Basic page Testing XPath XML Parser has been updated.');
    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
    $this->assertText('Updated 1 node.');
    $this->drupalGet('node');
    $this->assertText('Atom-Powered Robots Run Amok');
    $this->assertText('My dog Jack is the best.');
    $this->assertText('Physics is really cool.'); // The one that changed.
    $this->assertNoText('Physics is cool.'); // Make sure the old node is changed.
    // Be extra sure we updated.
    $this->drupalGet('node/4');
    $this->assertText('Physics is really cool.');

    // Check if replace existing nodes works.
    $this->setSettings('xpath_xml', 'FeedsNodeProcessor', array('update_existing' => 1));
    $edit = array(
      'feeds[FeedsHTTPFetcher][source]' => $path . 'sample_atom_feed.xml',
    );
    $this->postAndCheck($feed_node_edit_url, $edit, 'Save', 'Basic page Testing XPath XML Parser has been updated.');
    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
    $this->assertText('Updated 1 node.');
    $this->drupalGet('node');
    $this->assertText('Atom-Powered Robots Run Amok');
    $this->assertText('My dog Jack is the best.');
    $this->assertText('Physics is cool.'); // The one that changed.
    $this->assertNoText('Physics is really cool.'); // Make sure the old node is changed.
    // Be extra sure we updated.
    $this->drupalGet('node/4');
    $this->assertText('Physics is cool.');

    // Test that overriding default settings works.
    $edit = array(
      'feeds[FeedsXPathParserXML][xpath][context]' => '/foo',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:0]' => 'bar',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:1]' => 'baz',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:2]' => 'wee',
    );
    $this->postAndCheck($feed_node_edit_url, $edit, 'Save', 'Basic page Testing XPath XML Parser has been updated.');

    // Assert the we don't create an empty node when XPath values don't return anything.
    // That happened at one point.
    $this->drupalPost('node/' . $nid . '/import', array(), 'Import');
    $this->assertText('There are no new nodes.');

    // Test that validation works.
    $edit = array(
      'feeds[FeedsXPathParserXML][xpath][context]' => 'sdf asf',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:0]' => 'asdf[sadfas asdf]',
    );
    $this->drupalPost($feed_node_edit_url, $edit, 'Save');
    // Check for valid error messages.
    $this->assertText('There was an error with the XPath selector: Invalid expression');
    $this->assertText('There was an error with the XPath selector: Invalid predicate');
    // Make sure the fields are errored out correctly. I.e. we have red outlines.
    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsxpathparserxml-xpath-context"][1]/@class', 'form-text required error');
    $this->assertFieldByXPath('//input[@id="edit-feeds-feedsxpathparserxml-xpath-sources-xpathparser0"][1]/@class', 'form-text error');

    // Put the values back so we can test inheritance if the form was changed
    // and then changed back.
    $edit = array(
      'feeds[FeedsXPathParserXML][xpath][context]' => '//entry',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:0]' => 'title',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:1]' => 'id',
      'feeds[FeedsXPathParserXML][xpath][sources][xpathparser:2]' => 'id',
    );
    $this->postAndCheck($feed_node_edit_url, $edit, 'Save', 'Basic page Testing XPath XML Parser has been updated.');

    // Change importer defaults.
    $edit = array(
      'xpath[context]' => '//tr',
      'xpath[sources][xpathparser:0]' => 'booya',
      'xpath[sources][xpathparser:1]' => 'boyz',
      'xpath[sources][xpathparser:2]' => 'woot',
    );
    $this->postAndCheck($importer_url, $edit, 'Save', 'Your changes have been saved.');

    // Make sure the changes propigated.
    $this->drupalGet($feed_node_edit_url);
    $this->assertFieldByName('feeds[FeedsXPathParserXML][xpath][context]', '//tr');
    $this->assertFieldByName('feeds[FeedsXPathParserXML][xpath][sources][xpathparser:0]', 'booya');
    $this->assertFieldByName('feeds[FeedsXPathParserXML][xpath][sources][xpathparser:1]', 'boyz');
    $this->assertFieldByName('feeds[FeedsXPathParserXML][xpath][sources][xpathparser:2]', 'woot');
    // Check that our message comes out correct.
    $this->assertText('Field guid is mandatory and considered unique: only one item per guid value will be created.');

    // Check that allow_override works as expected.
    $this->setSettings('xpath_xml', 'FeedsXPathParserXML', array('xpath[allow_override]' => FALSE));
    $this->drupalGet($feed_node_edit_url);
    $this->assertNoText('XPath Parser Settings');
    $this->assertNoField('xpath[context]');
  }

  /**
   * Test variable substitution.
   */
  public function testVariables() {
    $this->createImporterConfiguration();

    $this->setPlugin('syndication', 'FeedsXPathParserXML');
    $importer_url = $this->feeds_base . '/syndication/settings/FeedsXPathParserXML';
    $this->addMappings('syndication', array(
      0 => array(
        'source' => 'xpathparser:0',
        'target' => 'title',
        'unique' => FALSE,
      ),
      1 => array(
        'source' => 'xpathparser:1',
        'target' => 'guid',
        'unique' => TRUE,
      ),
      2 => array(
        'source' => 'xpathparser:2',
        'target' => 'body',
      ),
    ));
    // Set importer default settings.
    $edit = array(
      'xpath[context]' => '//entry',
      'xpath[sources][xpathparser:0]' => 'title',
      'xpath[sources][xpathparser:1]' => 'id',
      'xpath[sources][xpathparser:2]' => 'link/@$title',
    );
    $this->postAndCheck($importer_url, $edit, 'Save', 'Your changes have been saved.');

    // Test import.
    $path = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds_xpathparser') . '/tests/feeds_xpathparser/';
    // We use an atom feed so that we can test that default namespaces are being
    // applied appropriately.
    $nid = $this->createFeedNode('syndication', $path . 'rewrite_test.xml', 'Testing XPath XML Parser');
    $feed_node_edit_url = 'node/' . $nid . '/edit';
    $this->assertText('Created 3 nodes');
    $this->drupalGet('node');
  }
}
