Using Codeception functional tests to POST data - php

I want to create a test which will directly post data to a Laravel page to test it handling bad data.
I can run an acceptance test starting at the page with the form on, call $I->click('Search'); and the page processes the data as expected.
Reading the introduction to Functional Tests on the Codeception website, it states
In simple terms we set $_REQUEST, $_GET and $_POST variables, then we execute your script inside a test, we receive output, and then we test it.
This sounds ideal, set an array of POST data and fire it directly at the processing page. But I can't find any documentation for it. I've played with sendAjaxPostRequest but it's not passing anything to $_POST.
Is there a way I can test the pages in isolation like this?

Turns out the solution lies with the Codeception REST module.
Adding this to the functional.suite.yml file allows you to write:
$I = new TestGuy($scenario);
$I->wantTo('check a page is resistant to POST injection');
$I->sendPOST(
'search',
array(
'startDate' => '2013-07-03',
'endDate' => '2013-07-10',
'exec' => 'some dodgy commands',
));
$I->see('Search results');
$I->dontSee('Dodgy command executed');
A little clunky, but it allows testing of a single page.

From the manual # http://codeception.com/docs/04-AcceptanceTests
$I->submitForm('#update_form', array('user' => array(
'name' => 'Miles',
'email' => 'Davis',
'gender' => 'm'
)));

Related

Does indices()->refresh() wait for completion?

I'm developing a PHP website using Elasticsearch (Official PHP client).
I'm writing tests that need to be sure the newly inserted documents
are ready to search before proceed.
To do this, after indexing new documents, I call:
$client->indices()->refresh()
My question is: Does $client->indices()->refresh() wait for refresh completion before making the PHP script go on? Or does not wait for its completion?
In the second hypothesis, how can make it wait for completion before making PHP test go on?
I know this is not exactly what was asked about refresh() but this is what I do to ensure a document is available to search as soon as it's indexed. I use the ?refresh parameter in the index operation:
$data = [
'type' => 'mytype',
'index' => 'myindex',
'id' => 'thisid',
'refresh' => 'wait_for',
'body' => [ /* document */ ]
];
$client->index($data);

CakePHP find method crashes on live server when more than a few entries

I'm encountering a strange error in CakePHP and I have no idea how to figure out what is going on.
I am using a Ajax request to load dynamic data for a dataTable and it works perfectly on my localhost. For some reason I can't get it to work on my live server when I have more than a few entries.
After debugging I found that it's the find function that is not working. When I have more than a few entries in my response array than one of the arrays('SollProject') is just simply completely empty and the whole script stops working.
Here is my Code:
$project = $this->Project->find("first", array('conditions'=>array('id'=>$project_id) ,
'contain' => array(
'SollProject' => array(
'conditions'=> array(
'SollProject.date >=' => $year.'-01-01',
'SollProject.date <=' => $year.'-12-31'
)
),
'HabenProject'=> array(
'conditions'=> array(
'HabenProject.date >=' => $year.'-01-01',
'HabenProject.date <=' => $year.'-12-31'
)
))));
Any idea what I am doing wrong here or why it is not working on the live server? There is no afterFind method in case you were wondering.
Maybe I should mention that I tried error debugging already and I don't get any error messages. I also tried the same sql code on my sql server and it works perfectly. There is also no memory issues since the memory I'm using is way beyound what I'm usually using and it's only a json response.
The function itself also works for small entries (not more than maybe 5 entries) but as soon as I have a little bit more entries in the database it just crashes.
The interesting thing is that I can debug($project['HabenProject']) and it shows me all HabenProject but if I try debug($project['SollProject']) or just debug($project) the variable is just empty. It's not even declared as array. There is just no output. The rest of the page is still showing.
Basic debugging steps:
Set debug to 2
Check your CakePHP apps logs
Check the php logs
Check the webserver logs
However, I guess it's a memory limit and debug is off, that's probably why you get a white page. Check the memory usage and increase the php memory limit.
Ok, after lots of debugging it looks like I found the problem:
For some reason every entry with an Umlaut (äüö) in the database produced an error that caused the result array of the find function to not work anymore.
Turns out the problem was the live server database utf-8 encryption was commented off...

Global registration issues when registering CLI params into GET

ran into a weird one here, maybe some of the more seniory of guys can help me come to a conclusion on what exactlies going on (already have a work around, but would like to know how to fix this as it seems it can affect other things)
So I have a line of code that will detect a CLI string (based on type[0]) and then proceed to convert and load CLI parameters into GET params.
parse_str(implode("&", array_slice($payload['args'], 1)), $_GET);
That works fine, you can test it with creating a file and issueing it something like
php - f test.php -- foo=bar bar=baz
With the contents of the file using the above line and just a print_r($_GET);
Well it get weird when you try to use this as a filter_input I've noticed but cannot figure out why
$filter = filter_input_array(INPUT_GET, [
'email' => FILTER_VALIDATE_EMAIL,
]);
print_r($filter); //empty
It also looks like trying to tack on anything to a GET request is forgone by filter_input_array in general, instance
http://localhost?request=foo
$_GET['email'] = 'Someguy#somplace.com';
//print_r($_GET); // check
print_r(filter_input_array(INPUT_GET, [
'email' => FILTER_VALIDATE_EMAIL,
'request' => FILTER_SANITIZE_ENCODED,
])):
What DOES work though for unknown reasons is
$filter = filter_var_array($_GET, [
'email' => FILTER_VALIDATE_EMAIL,
]);
Makes little to no sense to me =(
I would LIKE to believe that our GET somehow has not registered into the global scope, but I'm lacking on figuring out why...
I am running PHP 5.5.8 for Saucy, input welcome
The functions filter_input_array() and filter_input() work on the actual input, not on the corresponding global variables.
From a note in the documentation for filter_input:
Note that this function doesn't (or at least doesn't seem to) actually filter based on the current values of $_GET etc. Instead, it seems to filter based off the original values.
source

Routing not working properly on cake

I migrated a cake website from one server to another, but in statics pages is showing a blank page, this is happening in two case scenarios right now
Scenario1:
$this->redirect(Router::url(array('controller' => 'staticpages',
'action' => 'message', 'messageSlug' => 'welcome')));
Scenario2:
$link = Router::url(array('controller' => 'staticpages',
'action' => 'message', 'messageSlug' => 'thanks-for-registering'));
The Facebook PHP SDK is interfering. It's probably throwing an error before Cake can properly redirect (the headers are already sent by groofi__extra_facebook.php.
Have a look what's happening in groofi__extra_facebook.php where the error seems to be stemming from. Probably your new server configuration is missing a vital component, is cURL present, for example?

Drupal - Protect form data from tampering

function simple_form($form_state) {
$form['item'] = array('#type' => 'hidden', '#value' => 'some_value');
$form['#action'] = 'http://external-website.com/';
$form['submit'] = array(
'#type' => 'submit',
);
return $form;
}
Simple Drupal form, gets called with drupal_get_form(simple_form).
Unfortunately, it is really easy to change the value of 'item' to something else in the form, and then send that value to the external site.
As far as I tried, there is no way to check the form before it leaves my site.
function simple_form_validate() and submit never get called.
How can I prevent that? Set the action to an internal function and then submit it after validating? How would I go about that?
Unfortunately, setting
$form['item'] = array('#type' => 'value', '#value' => 'some_value');
doesn't work? The external site doesn't receive the value for 'item'.
Any advice?
It is either/or. and that has nothing to do with Drupal, but with the nature of HTTP POST.
Either you use #type=>value and Drupal maintains its storage outside of the form, inside of Drupal, trough a session,
Or you post to external, in which case that internal session storage cannot help.
Drupals security system in the Form API relies on the fact that Drupal "knows" the exact form itself and therefore can avoid incorrect values, by comparing them to the original form.
An external site knows nothing about the original form, and therefore knows nothing about how to validate it.
You will need to perform validation on the end of the receiver of the POST (that external site), nothing else will be secure (enough).
That validation could be a local script running on the remote site, wich simply validates against whitelists or regular expressions.
Alternatively, that remote site could request (e.g. over HTTP-SOAP, or XMLRPC) the form on the original Drupal-site, but that is going to be pretty hard to achieve.
A third alternative, and IMHO the simplest, is to let Drupal handle the entire form locally, and if validated process it in the submit hook. In there, you can either post the values to the remote site in a secure way, or you can simply stick it in the database or some spool-system of that remote site. In any case: in the submit hook, after Drupal validated the form, you push it on to the remote site.

Categories