<?php
/**
* Class PhpXformsTest
*
* Currently lacks tests for set***Callback() methods (I wonder if it is really needed)
*
* $Id$
*/
require_once PHP_XFORMS_ROOT . '/PhpXforms.php';
class PhpXformsTest extends UnitTestCase {
/**
* XmlSchema used to validate user-submitted data
*/
const SCHEMA = '<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<xs:simpleType name="title">
<xs:restriction base="content">
<xs:maxLength value="255" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="content">
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse"/>
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
<xs:element name="article">
<xs:complexType>
<xs:sequence>
<xs:element name="publishdate" type="xs:date" />
<xs:element name="title" type="title" />
<xs:element name="content" type="content" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>';
/**
* Data that should pass through XmlSchema validation
*/
const SCHEMA_VALID_DATA = '<?xml version="1.0" encoding="utf-8" ?>
<article>
<publishdate>2006-09-04</publishdate>
<title>This is valid data</title>
<content>This is valid content</content>
</article>';
/**
* Data that should fail XmlSchema validation
*/
const SCHEMA_INVALID_DATA = '<?xml version="1.0" encoding="utf-8" ?>
<article>
<publishdate>2006-09-04</publishdate>
<title>a string longer than maximum of 255 symbols, which is maximum as defined by schema.
a string longer than maximum of 255 symbols, which is maximum as defined by schema.
a string longer than maximum of 255 symbols, which is maximum as defined by schema.
a string longer than maximum of 255 symbols, which is maximum as defined by schema.</title>
<content>This is valid content</content>
</article>';
const DATA_NOT_VALID = 'Data is not valid';
/**
* @var PhpXforms
*/
protected $xforms;
/**
* @var array
*/
protected $data;
function testValidDataPassesSchemaValidation()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
try {
$this->xforms->run();
} catch (PhpXformsException $e) {
$this->assertTrue(false, 'Valid data shoud not raise a validation exception!');
}
}
function testInvalidDataFailsSchemaValidation()
{
$this->xforms->setXmlSource(self::SCHEMA_INVALID_DATA);
try {
$this->xforms->run();
$this->assertTrue(false, 'Should never get here! An exception should be raised!');
} catch (PhpXformsException $e) {
$this->assertTrue(true);
}
}
/**
* ??? Possibly, we should as well test external validation which does not produce errors?
*/
function testExternalValidationErrorCausesExceptionThrow()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
$this->xforms->setValidator($this, 'validateWithError');
try {
$this->xforms->run();
$this->assertTrue(false, 'Should never get here! An exception should be raised!');
} catch (Exception $e) {
$this->assertTrue(true);
}
}
function testDataProcessingWithNoErrors()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
$this->xforms->setProcessor($this, 'processDataNoErrors');
$this->xforms->run();
$this->assertTrue(is_array($this->data));
$this->assertEqual('This is valid content', $this->data['content']);
}
function testDataProcessingErrorRaisesException()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
$this->xforms->setProcessor($this, 'processDataWithError');
try {
$this->xforms->run();
$this->assertTrue(false, 'Should never get here! An exception should be raised!');
} catch (Exception $e) {
$this->assertTrue(true);
}
}
function testDefaultExceptionHandler()
{
$this->xforms->setXmlSource(self::SCHEMA_INVALID_DATA);
$this->xforms->setDefaultExceptionHandler();
ob_start();
$this->xforms->run();
$sxml = @ simplexml_load_string(ob_get_clean());
$this->assertIsA($sxml, 'SimpleXMLElement');
$this->assertTrue(strlen((string) $sxml->error) > 0);
}
/**
* @see handleException()
*/
function testCustomExceptionHandler()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
$this->xforms->setExceptionHandler($this, 'handleException');
$this->xforms->setValidator($this, 'validateWithError');
$this->xforms->run();
$this->assertEqual(self::DATA_NOT_VALID, $this->data);
}
function testDefaultSuccessHandler()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
$this->xforms->setDefaultSuccessProcessor();
ob_start();
$this->xforms->run();
$sxml = @ simplexml_load_string(ob_get_clean());
$this->assertIsA($sxml, 'SimpleXMLElement');
$this->assertFalse($sxml->error);
}
/**
* @see handleSuccess()
*/
function testCustomSuccessHandler()
{
$this->xforms->setXmlSource(self::SCHEMA_VALID_DATA);
$this->xforms->setSuccessProcessor($this, 'handleSuccess');
$this->xforms->run();
$this->assertEqual('success', $this->data);
}
function testRetrievingHTTP_RAW_POST_DATA()
{
// emulate POST request
$_SERVER['REQUEST_METHOD'] = 'POST';
$GLOBALS['HTTP_RAW_POST_DATA'] = self::SCHEMA_VALID_DATA;
try {
$this->xforms->run();
} catch (PhpXformsException $e) {
$this->assertTrue(false, 'Valid data shoud not raise a validation exception!');
}
}
function testErrorInRetrievingHTTP_RAW_POST_DATARaisesException()
{
// illegal request method
$_SERVER['REQUEST_METHOD'] = 'GET';
try {
$this->xforms->run();
$this->assertTrue(false, 'Should never get here! An exception should be raised!');
} catch (Exception $e) {
$this->assertTrue(true);
}
}
function testReadingSchemaFromFile()
{
$filename = dirname(__FILE__) . '/schema.xsd';
file_put_contents($filename, self::SCHEMA);
$xforms = new PhpXforms($filename);
$xforms->setXmlSource(self::SCHEMA_VALID_DATA);
try {
$xforms->run();
} catch (PhpXformsException $e) {
$this->assertTrue(false, 'Valid data shoud not raise a validation exception! ');
}
unlink($filename);
}
/**
* Sample validator function
*
* @param array $data
* @throws Exception
*/
function validateWithError(array $data)
{
throw new Exception(self::DATA_NOT_VALID);
}
/**
* Sample processor function
*
* @param array $data
*/
function processDataNoErrors(array $data)
{
$this->data = $data;
}
/**
* Sample processor function which produces error
*
* @param array $data
*/
function processDataWithError(array $data)
{
throw new Exception('Data processing error');
}
/**
* Sample custom exception handler
*
* @param Exception $e
*/
function handleException(Exception $e)
{
$this->data = $e->getMessage();
}
/**
* Sample custom success handler
*/
function handleSuccess()
{
$this->data = 'success';
}
/**
* Setup fixture
*/
function setUp()
{
$this->xforms = new PhpXforms(self::SCHEMA, true);
}
}