<?php
namespace Phad\Test\Integration;
/**
* This class appears to test both form compilation and form submission
*
* @notice Several of these tests incidentally test the submit target/redirect feature.
*/
class Forms extends \Phad\Tester {
protected array $blogTableColumns = ['id'=>'INTEGER PRIMARY KEY','title'=>'VARCHAR(200)', 'body'=>'VARCHAR(2000)'];
public function testDeleteItem(){
$lildb = \Tlf\LilDb::sqlite();
$pdo = $lildb->pdo();
$phad = $this->phad();
$phad->pdo = $pdo;
$lildb->create('blog',['id'=>'integer', 'title'=>'varchar(90)']);
$lildb->insert('blog',['id'=>1,'title'=>'title 1']);
$lildb->insert('blog',['id'=>2,'title'=>'title 2']);
$lildb->insert('blog',['id'=>3,'title'=>'title 3']);
$form = new \Phad\View('Form/Deleteable', $this->file('test/input/views/'),
['id'=>2, 'phad'=>$phad]);
$form->force_compile = true;
$form->delete();
$blogs = $lildb->select('blog');
$this->compare(
[ ['id'=>1,'title'=>'title 1'],
['id'=>3,'title'=>'title 3'],
],
$blogs
);
}
public function testErrorMessage(){
$pdo = $this->getPdo();
$phad = $this->phad();
$phad->pdo = $pdo;
$view = $phad->view('Form/SimpleBlogWithError');
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$BlogRow = ['body'=>'smol body', 'title'=>''];
$out = $view->submit($BlogRow);
$msg = $phad->validationErrorMessage($phad->failed_submit_columns);
$this->test('Error Message Written');
$this->str_not_contains($out, ['<error>','</error>']);
$this->str_contains($out, '<div class="my-error-class">'.$msg.'</div>');
$this->test('Headers empty');
$this->compare(
[],
$phad->getHeaders(),
);
}
public function testSubmitDocumentation(){
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$ldb = \Tlf\LilDb::sqlite();
$pdo = $ldb->pdo();
$ldb->create('blog', $this->blogTableColumns);
$phad = $this->phad();
$phad->pdo = $pdo;
$view = $phad->view('Form/SimpleBlogNoTarget');
//if `id` were set, an UPDATE would be done instead.
$BlogRow = ['title'=>'Fine Title', 'body'=>'I have to be at least 50 characters. But that isn\'t very long.'];
$out = $view->submit($BlogRow);
$BlogRow['id'] = $pdo->lastInsertId();
$headers = $phad->getHeaders();
//you can foreach(as $h){ header(...$h) }
//@export_end(Forms.ManualSubmission)
$this->test('Headers');
$this->compare(
[['Location: https://localhost/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Inserted');
$this->compare(
[$BlogRow],
$ldb->query('SELECT * FROM blog')
);
}
public function testControllerOnSubmitDocumentation(){
$phad = new class() extends \Phad {
public function onSubmit($ItemData, &$ItemRow){
if ($ItemData->name!='Blog')return true;
$ItemRow['slug'] = str_replace(' ', '-', strtolower($ItemRow['title']));
return true;
}
};
$pdo = $this->getPdo();
$phad = $this->phad($phad);
$phad->pdo = $pdo;
$phad->target_url = '/blog/{slug}/{id}/';
$cols = $this->blogTableColumns;
$cols['slug'] = 'VARCHAR(100)';
$this->createTable($pdo, 'blog', $cols);
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$BlogRow =
[
'title'=>'Fine Title',
'body'=>'I have to be at least fifty characters. That shouldn\'t be much of a problem, though it does require a bit more typing. And if I had something original to say, that would make it better.'
];
/** anonymous class to use as our controller */
/** passing our custom controller & submitting manually */
$view = $phad->view('Form/SimpleBlogNoTarget');
/** $BlogRow is just an array with 'title' & 'body' **/
$output = $view->submit($BlogRow);
$BlogRow['id'] = $pdo->lastInsertId();
$BlogRow['slug'] = 'fine-title';
$this->test('There should be no output');
$this->handleDidPass(strlen(trim($output))===0);
$this->test('Headers');
$this->compare(
[['Location: https://localhost/blog/fine-title/'.$BlogRow['id'].'/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Inserted');
$this->compare(
$BlogRow,
$this->queryOne($pdo, 'SELECT * FROM blog'),
);
}
public function testWithInlineOnSubmit(){
$pdo = $this->getPdo();
$phad = $this->phad();
$phad->pdo = $pdo;
$phad->target_url = '/blog/{slug}/{id}/';
$cols = $this->blogTableColumns;
$cols['slug'] = 'VARCHAR(100)';
$this->createTable($pdo, 'blog', $cols);
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$BlogRow =
[
'title'=>'Fine Title',
'body'=>'I have to be at least fifty characters. That shouldn\'t be much of a problem, though it does require a bit more typing. And if I had something original to say, that would make it better.'
];
$view = $phad->view('Form/BlogWithOnSubmit');
$output = $view->submit($BlogRow);
$BlogRow['id'] = $pdo->lastInsertId();
$BlogRow['slug'] = 'fine-title';
$this->test('Backend Prop is removed');
$this->str_not_contains($phad->view('Form/BlogWithOnSubmit', $BlogRow), 'type="backend"');
$this->test('<onsubmit> tag was removed');
$this->str_not_contains($phad->view('Form/BlogWithOnSubmit', $BlogRow), '<onsubmit>');
$this->test('There should be no output');
$this->handleDidPass(strlen(trim($output))===0);
$this->test('Headers');
$this->compare(
[['Location: https://localhost/blog/fine-title/'.$BlogRow['id'].'/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Inserted');
$this->compare(
$BlogRow,
$this->queryOne($pdo, 'SELECT * FROM blog'),
);
}
public function testInsertWithValidOption(){
$pdo = $this->getPdo();
$phad = $this->phad();
$phad->pdo = $pdo;
$view = $phad->view('Form/BlogWithCategories');
$cols = $this->blogTableColumns;
$cols['category'] = 'VARCHAR(100)';
$this->createTable($pdo, 'blog', $cols);
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$BlogRow = ['title'=>'Police Brutality super sucks', 'body'=>'Its been well documented that police brutality is a reality, yet there\'s still overwhelming controversy about what we should do with our society. Some say: Let the police to what they gotta do. Others say: Lets rethink this society that\'s built upon punishing people who misbehave & actually help people instead. Mayb ewe could redirect some of the MASSIVE tax dollars that go to police departments to actually help someone. That\'s me. I say that. - Reed',
'category'=>'Police Brutality'];
$out = $view->submit($BlogRow);
$BlogRow['id'] = $pdo->lastInsertId();
$this->test('There should be no output');
$this->handleDidPass(strlen(trim($out))===0);
$this->test('Headers');
$this->compare(
[['Location: https://localhost/blog/'.$BlogRow['title'].'/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Inserted');
$this->compare(
$BlogRow,
$this->queryOne($pdo, 'SELECT * FROM blog'),
);
}
public function testUpdateRedirectsToTarget(){
// $phad = $this->phad();
$pdo = $this->getPdo();
// $phad->pdo = $pdo;
$this->createTable($pdo, 'blog', $this->blogTableColumns);
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$phad = new class() extends \Phad {
public function t(){
echo "\ntttttttttttttttt\n";
}
public function objectFromRow($ItemData, $BlogRow){
$Blog = (object)$BlogRow;
$Blog->slug = str_replace(' ', '-', strtolower($Blog->title));
return $Blog;
}
};
$phad = $this->phad($phad);
$phad->target_url = '/blog/{slug}/{id}/';
$phad->pdo = $pdo;
$view = $phad->view('Form/SimpleBlogNoTarget', ['phad'=>$phad]);
$BlogRow =
[
'title'=>'Fine Title',
'body'=>'I have to be at least fifty characters. That shouldn\'t be much of a problem, though it does require a bit more typing. And if I had something original to say, that would make it better.'
];
$out = $view->submit($BlogRow);
$BlogRow['id'] = $pdo->lastInsertId();
$this->test('There should be no output');
$this->handleDidPass(strlen(trim($out))===0);
$this->test('Headers');
$this->compare(
[['Location: https://localhost/blog/fine-title/'.$BlogRow['id'].'/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Inserted');
$this->compare(
$BlogRow,
$this->queryOne($pdo, 'SELECT * FROM blog'),
);
}
public function testUpdateValid(){
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$ldb = \Tlf\LilDb::sqlite();
$phad = $this->phad();
$phad->pdo = $ldb->pdo();
$view = $phad->view('Form/SimpleBlog');
$ldb->create('blog', $this->blogTableColumns);
$BlogRow = ['id'=>0, 'title'=>'Fine Title', 'body'=>'I have to be at least fifty characters. That shouldn\'t be much of a problem, though it does require a bit more typing. And if I had something original to say, that would make it better.'];
$ldb->insert('blog', $BlogRow);
$UpdatedBlog = $BlogRow;
$UpdatedBlog['title'] = 'New Title';
$out = $view->submit($UpdatedBlog);
$this->test('Headers');
$this->compare(
[['Location: https://localhost/blog/'.$UpdatedBlog['title'].'/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Updated');
$this->compare(
[$UpdatedBlog],
$ldb->query('SELECT * FROM blog')
);
$this->test('No Output Present');
$this->compare(
'',
trim($out)
);
}
public function testInsertValid(){
$phad = $this->phad();
$phad->pdo = $this->getPdo();
$view = $phad->view('Form/SimpleBlog');
$this->createTable($phad->pdo, 'blog', $this->blogTableColumns);
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['HTTPS'] = 'non-empty-value';
$BlogRow = ['title'=>'Fine Title', 'body'=>'I have to be at least fifty characters. That shouldn\'t be much of a problem, though it does require a bit more typing. And if I had something original to say, that would make it better.'];
$out = $view->submit($BlogRow);
$BlogRow['id'] = $phad->pdo->lastInsertId();
$this->test('There should be no output');
$this->handleDidPass(strlen(trim($out))===0);
$this->test('Headers');
$this->compare(
[['Location: https://localhost/blog/'.$BlogRow['title'].'/', true]],
$phad->getHeaders(),
);
$this->test('Data Was Inserted');
$this->compare(
$BlogRow,
$this->queryOne($phad->pdo, 'SELECT * FROM blog'),
);
}
/**
* @test that a partially filled in form is returned when submission fails.
*/
public function testSubmitInvalid(){
$phad = $this->phad();
$phad->force_compile = false;
$this->createTable($phad->pdo, 'blog', $this->blogTableColumns);
// View contains:
// <textarea name="body" maxlength="2000" minlength="50"></textarea>
$view = $phad->view('Form/SimpleBlog');
// should fail because body is less than 50 chars
$Blog = ['title'=>'Fine Title', 'body'=>'body too short'];
$out = $view->submit($Blog);
$Blog = (object)$Blog;
echo $out;
$this->test('Form cleaned up');
$this->str_not_contains($view, ['item=']);
$this->test('Submitted Blog Content');
$this->str_contains($out, 'value="'.$Blog->title.'"');
$this->str_contains($out, '>'.$Blog->body.'</textarea>');
}
public function testDisplayWithNoObject(){
$view = $this->view('Form/SimpleBlog');
$Blog = ['title'=>'Fine Title', 'body'=>'body too short'];
$out = $view->outputWithEmptyObject($Blog);
$Blog = (object)$Blog;
echo $out;
$this->test('Form cleaned up');
$this->str_not_contains($out, ['item=']);
$this->test('Target Attribute Removed');
$this->str_not_contains($out, 'target="');
$this->test('Submitted Blog Content');
$this->str_contains($out, 'value=""');
$this->str_contains($out, '></textarea>');
}
/**
* @test getting each selectable-option from a form's compiled view
*/
public function testHasSelectOptions(){
$view = $this->view('Form/BlogWithCategories');
$ItemData = $view->getItemData();
$expect = [
'title' =>
[
'type' => 'text',
'maxlength' => '75',
'tagName' => 'input',
],
'body' =>
[
'maxlength' => '2000',
'minlength' => '50',
'tagName' => 'textarea',
],
'category'=>
[
'tagName'=> 'select',
'options'=>[
"social-justice",
"policy",
"Police Brutality",
"Election",
],
],
'id'=>
[
'tagName'=>'input',
'type'=>'hidden',
]
];
$this->compare($expect, $ItemData->properties);
}
/**
* @test getting info about properties from the compiled view.
*/
public function testHasPropertiesData(){
$view = $this->view('Form/SimpleBlog');
$ItemData = $view->getItemData();
$expect = [
'title' =>
[
'type' => 'text',
'maxlength' => '75',
'tagName' => 'input',
],
'body' =>
[
'maxlength' => '2000',
'minlength' => '50',
'tagName' => 'textarea',
],
'id'=>
[
'tagName'=>'input',
'type'=>'hidden',
]
];
$this->compare($expect, $ItemData->properties);
}
}