<?php
namespace Phad\Test\Main;
class Server extends \Phad\Tester {
public function testUploadFileFail(){
$documents = $this->post('/document/make/',
['title'=>'PD Use of Force Report'],
['doc'=>$this->file('test/Server/for-upload/use-of-force-report.txt')]
);
// echo $documents;
$clean = trim( substr($documents, 0,strpos($documents, '(')) );
$this->compare(
'PD Use of Force Report:use-of-force-report.txt#275',
$clean,
);
// echo $clean;
}
/**
* @test failing a submission when required properties are missing
* @test partially filled form is delivered when prop requirements are not met
*/
public function testFailedSubmissionRequiredProperties(){
$list = $this->get('/blog-names/');
$create = $this->post('/blog/required-props/', ['title'=>'This should fail', 'body'=>'']);
$list_after = $this->get('/blog-names/');
$this->compare($list, $list_after);
echo $create;
$this->str_contains($create,
['<input type="text" name="title" maxlength="75" required value="This should fail">',
'<textarea name="body" maxlength="2000" minlength="10" required></textarea>',
]
);
}
/**
* @test failing a submission bc access is not gratned
* @test that failed submission response has blank output
*/
public function testFailedAccessForSubmission(){
$list = $this->get('/blog-names/');
$create = $this->post('/blog/make/?deny_access=true', ['title'=>'This should fail', 'body'=>'']);
$list_after = $this->get('/blog-names/');
$this->compare($list, $list_after);
echo $create;
$empty_form = $this->get('/blog/make/');
$target = str_replace('value=""', 'value="This should fail"', $empty_form);
$this->compare($target,$create);
}
/**
* @test being able to create an item, but NOT delete an item
*/
public function testCreateNoDelete(){
$this->bootstrap();
$form = $this->get('/create-no-delete/?phad_action=delete&id=1');
echo $form;
$this->str_contains($form, "<p>Deleting 'Candelete' rejected by 'call:never_allow'</p>");
$create = $this->post('/create-no-delete/',
$post=[
// 'id'=>10,
'title'=>'Created under pressure',
]
);
echo $create;
$this->str_contains($create,
[
'1-I like bears a lot',
'4-Created under pressure,'
]
);
}
/**
* @test deletion runs custom access handlers
*/
public function testRejectDeleteAccessWithCustomHandler(){
$this->bootstrap();
$form = $this->get('/delete-not-allowed/?phad_action=delete&id=1');
echo $form;
$this->str_contains($form, "<p>Deleting 'Candelete' rejected by 'call:never_allow'</p>");
$this->str_not_contains($form, '</form><form');
}
/**
* @test forms only enable deletion if `candelete` attribute is set.
*/
public function testFailToDeleteNonCandelete(){
$form = $this->get('/blog/make/?phad_action=delete&id=1');
echo $form;
$parts = explode('<form',$form);
$this->is_true(count($parts)==2);
$this->str_contains(
$form,
'value="I like bears a lot"',
'>Like seriously, I really love bears. They\'re so cute.</textarea>',
);
}
/**
*
* @test that a custom function successfully handles a deletion response
* @test that trying to delete a non-existent item still calls the custom handler
*/
public function testDeleteCustomResponse(){
// $this->bootstrap();
$delete_fail = $this->get('/candelete-custom/?phad_action=delete&id=20');
$this->compare("This is my custom deletion response. I don't care if deletion succeeded. Id was 20", $delete_fail);
}
public function testDeleteFailNotFound(){
// $this->bootstrap();
$delete_fail = $this->get('/candelete/?phad_action=delete&id=20');
$this->compare("Cannot delete 'Candelete'. None exist with id '20'", $delete_fail);
}
public function testDeletePrint(){
$this->bootstrap();
// $this->benchStart();
$delete = $this->get('/candelete-print/?phad_action=delete&id=2');
$this->compare('WooHoo! Delete!', $delete);
}
public function testDeleteRedirect(){
$this->bootstrap();
$delete = $this->get('/candelete-redirect/?phad_action=delete&id=2');
$this->compare('index page', $delete);
}
/**
* @test deleting an item via request
* @test 'success' response for deletion
*/
public function testDeleteResponse(){
$this->bootstrap();
$delete = $this->get('/candelete/?phad_action=delete&id=2');
$this->test('deletion response');
$this->compare("Successfully deleted Candelete with id '2'", $delete);
$this->test('deletion succeeded');
$posts = $this->get('/candelete-list/');
// echo $posts;
$this->compare(
'1-I like bears a lot,3-Baby Fires,',
$posts
);
}
public function testDeleteItemS(){
$this->bootstrap();
$delete = $this->get('/candelete/?phad_action=delete&id=2');
echo $delete;
$posts = $this->get('/candelete-list/');
// echo $posts;
$this->compare(
'1-I like bears a lot,3-Baby Fires,',
$posts
);
}
/**
* @test custom hasRowAccess() implementation
*/
public function testCustomRowAccess(){
$blogs_json = $this->get('/blog-list/?custom_access=true&permit_me=true&get=json');
// var_dump($blogs_json);
// exit;
$blogs = json_decode($blogs_json, true);
// print_r($blogs);
// echo $blogs_json;
// exit;
$this->is_true(count($blogs)===3);
// $target = $blogs['BlogList'][0];
$target = $blogs[0];
$blogs_json = $this->get(
'/blog-list/'
.'?custom_access=true&permit_me=true&get=json'
.'&title='.urlencode('I like bears a lot')
);
// echo $blogs_json;
$this->compare([$target],
json_decode($blogs_json,true)
);
}
public function testApproveCustomAccess(){
$access = $this->get('/access2/?custom_access=true&permit_me=true&user=admin');
echo $access;
$this->str_contains($access, '<!-- access-granted -->');
$this->str_not_contains($access, 'Blogs Not Found');
$this->str_contains($access, 'Access Granted');
$this->str_contains($access, '<h1>Before Item Node</h1>');
$this->str_contains($access, '<h2>After Item Node</h2>');
}
/**
* @test custom access handlers
*/
public function testDenyCustomAccess(){
// ?permit_me=true is just a really simple way to test this
$access = $this->get('/access2/?custom_access=true&permit_me=false&user=admin');
echo $access;
$this->str_not_contains($access, '<!-- access-granted -->');
$this->str_not_contains($access, 'Blogs Not Found');
$this->str_contains($access, '<h1>Before Item Node</h1>');
$this->str_contains($access, '<h2>After Item Node</h2>');
// this 403 error displays bc of the `permit_me` access handler returning false, even though the role passes
$this->str_contains($access, 'User does not have admin role. User has role admin');
}
public function testDenyRoleAccess(){
$access = $this->get('/access/?user=guest');
echo $access;
$this->str_not_contains($access, '<!-- access-granted -->');
$this->str_not_contains($access, 'Blogs Not Found');
$this->str_contains($access, '<h1>Before Item Node</h1>');
$this->str_contains($access, '<h2>After Item Node</h2>');
$this->str_contains($access, 'User does not have admin role. User has role guest');
}
public function testApproveRoleAccess(){
$access = $this->get('/access/?user=admin');
echo $access;
$this->str_contains($access, '<!-- access-granted -->');
$this->str_not_contains($access, 'Blogs Not Found');
$this->str_contains($access, 'Access Granted');
$this->str_contains($access, '<h1>Before Item Node</h1>');
$this->str_contains($access, '<h2>After Item Node</h2>');
}
public function testUploadFile(){
$documents = $this->post('/document/make/',
['title'=>'PD Use of Force Report'],
['doc'=>$this->file('test/Server/for-upload/use-of-force-report.txt')]
);
// echo $documents;
$clean = trim( substr($documents, 0,strpos($documents, '(')) );
$this->compare(
'PD Use of Force Report:use-of-force-report.txt#275',
$clean,
);
// echo $clean;
}
/**
* @test editing an existing item by passing `id` via GET
*/
public function testEditBlogForm(){
$form = $this->get('/blog/make/?id=1');
echo $form;
$parts = explode('<form',$form);
$this->is_true(count($parts)==2);
$this->str_contains(
$form,
'value="I like bears a lot"',
'>Like seriously, I really love bears. They\'re so cute.</textarea>',
);
$this->str_not_contains(
$form,
'</form><form',
);
}
/**
* @test redirecting to target after post submission
*/
public function testBlogFormRedirect(){
$post_output = $this->post('/blog/make/',
$post=[
'title'=>'The New Post',
'body'=> 'Hopefully this submits to db without any issue.',
]
);
echo $post_output;
// assert only 1 <h1>
$parts = explode('<h1>',$post_output);
$this->is_true(count($parts)==2);
$this->str_contains(
$post_output,
'<h1>The New Post</h1>',
'<p>'.$post['body'].'</p>',
);
}
/** @test inserting data via POST */
public function testSubmitBlogForm(){
$names_before = $this->get('/blog-names/');
$post_output = $this->post('/blog/make/',
$post=['title'=>'A New Post',
'body'=> 'Hopefully this submits to db without any issue.',
]
);
echo $post_output;
$names_after = $this->get('/blog-names/');
$this->compare('A New Post,'.$names_before,
$names_after
);
}
public function testGetBlogForm(){
$form = $this->get('/blog/make/');
echo $form;
$parts = explode('<form',$form);
$this->is_true(count($parts)==2);
$this->str_contains(
$form,
'<input ',
'<textarea',
'></textarea>',
);
}
public function testNestedViews(){
$out = $this->get('/nested/');
$json = $this->get('/nested/?get=json');
echo $out;
print_r(json_decode($json,true));
$this->str_contains($out,
'<h2>Bear</h2>',
'<b>Reed</b>',
'<b>Jalin</b>',
'<h2>Goose</h2>',
'<b>PooPooMaShu</b>',
'<b>Baroney</b>',
);
// echo $json;
// exit;
//@todo re-enable nested items in getting array of data
$target = '[{"id":"1","name":"Bear"},{"id":"2","name":"Goose"}]';
// $target = '{"SpeciesList":[{"id":"1","name":"Bear","CharacterList":[{"id":"1","name":"Reed","level":"10","species":"1"},{"id":"2","name":"Jalin","level":"10","species":"1"}]},{"id":"2","name":"Goose","CharacterList":[{"id":"3","name":"PooPooMaShu","level":"10","species":"2"},{"id":"4","name":"Baroney","level":"10","species":"2"}]}]}';
$this->compare_json($target, $json);
}
public function testQueryCharacterJson(){
$dirty = $this->get('/characters/?get=json');
$pretty = $this->get('/characters/?get=json&prettyprint=true');
$expect = '[{"id":"1","name":"Reed","level":"10","species":"Bear"},{"id":"2","name":"Jalin","level":"10","species":"Bear"},{"id":"3","name":"PooPooMaShu","level":"10","species":"Goose"},{"id":"4","name":"Baroney","level":"10","species":"Goose"}]';
echo $pretty;
$this->compare_json($expect, $dirty);
$this->compare_json($expect, $pretty);
$this->str_contains($pretty,"\n");
$this->str_not_contains($dirty,"\n");
}
public function testSimpleSpeciesQuery(){
$out = $this->get('/species/');
echo $out;
$this->str_contains($out,
'<span>Bear</span>#<span>1</span>',
'<span>Goose</span>#<span>2</span>',
);
}
public function testQueryCharacterView(){
$out = $this->get('/characters/');
echo $out;
$this->str_contains($out,
[
'<h2>Reed</h2>',
'<h2>Jalin</h2>',
'<h2>PooPooMaShu</h2>',
'<h2>Baroney</h2>',
'<p>Species: Bear</p>',
'<p>Species: Goose</p>',
]
);
}
public function testServeSitemap(){
$out = $this->get('/sitemap.xml');
echo $out;
$target =
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<changefreq>daily</changefreq>
<lastmod>1354</lastmod>
<loc>/sitemapped/</loc>
<priority>0.8</priority>
</url>
<url>
<changefreq>weekly</changefreq>
<lastmod>123</lastmod>
<loc>/sitemapped2/</loc>
<priority>0.5</priority>
</url>
</urlset>
XML;
$this->compare($target, $out);
}
public function testGetDynamicRoute(){
$out = $this->get('/phad-routed/i-like-bears/');
echo $out;
$this->str_contains($out, 'Param is i-like-bears');
$this->str_contains($out,'This is routed to by Phad, but contains no items');
}
public function testRouted(){
$out = $this->get('/phad-routed/');
echo $out;
$this->str_contains($out,'This is routed to by Phad, but contains no items');
}
/**
* @test that explicitly invoking phad outputs correct data
*/
public function testExplicit(){
$out = $this->get('/explicit/');
echo $out;
$this->str_contains(
$out,
[
'<li>One</li>',
'<li>Two</li>',
'<li>Three</li>',
'<li>Four</li>',
]
);
}
/**
* @test that the server is running & has basic functionality
*/
public function testVerify(){
$out = $this->get('/verify/');
$this->compare('__Phad__', $out);
}
}