I wrote a method to test my code , but problem is when I use dataProvider i got :
1) Warning
The data provider specified for userTest::testItCanValidateApiKeysAndDomainAutoTest is invalid.
Call to undefined function show_message()
WARNINGS!
Tests: 5, Assertions: 12, Warnings: 1.
here is my code when i use it without dataProvider
public function testItCanValidateApiKeysAndDomainByInputData(){
$this->user->setApiKey('306942ac');
$this->user->setDomain('test.com');
$this->assertEquals(show_message(103), $this->user->verifyPurchaseKey());
}
and it work fantastic , but when i use dataProvider
public function inputApiKeys()
{
return array(
array(
'f5e47ee75672b855a8d76f5d54aa7ce6914',
'reza.com',
false,
),
array(
'f5e47asdasdasd',
'reza.com',
show_message(100),
),
array(
'0ecc580a009d929b13337509721a4',
'test12.com',
show_message(102),
),
array(
'0ecc580a009d9230604659b13337509721a4',
'127.0.0.1',
show_message(1,
'6233c772-e214-a45d8c1e04e2'),
),
array(
'0ecc580a009d9204659b13337509721a4',
'localhost',
show_message(1,
'6233c772a45d8c1e04e2'),
),
array(
'ac45e9ff50c5aac05d25c2605d2195f33b4',
'mm.mu.com',
show_message(102),
),
array(
'ac45e9f1aeab519f50c5aac05d25c2605d2195f33b4',
'reza.wpengine.com',
show_message(103),
),
array(
'000604659b13337509721a4',
'mnm.wpengine.com',
'6233c772-3-9cc4-a45d8c1e04e2'),
);
}
/**
* #dataProvider inputApiKeys
*/
public function testItCanValidateApiKeysAndDomainAutoTest($apikey, $domain, $result)
{
$this->user->setApiKey($apikey);
$this->user->setDomain($domain);
$this->assertEquals($result, $this->user->verifyPurchaseKey());
}
you may consider that i use show_message in another file loaded by autoload to project ..
got warning message ..
It's important to return the created data structure at the end of your data provider function:
return $reza;
This should normally make it work. At least I tried your code and it works here if I declare a show_message() function globally.
The message Call to undefined function show_message() indicates that this function is not in the scope of your data provider. That seems strange if calling show_message() directly in your test function works. So I think, there might be something more different in your code when you didn't use the the data provider.
Related
Did someone tried the tutorial about Sortable Sonata Type Model in Admin.
I've followed it step by step without missing anything (I'm pretty sure) but can't get a good result at the end.
Basically what I'm trying to do is : I have 3 entities, Article, Tag and ArticleTag (eq to User, Expectation and UserHasExpectation in the tutorial)
Everything seems good until the UserHasExpectationAdmin:
protected function configureFormFields(FormMapper $formMapper){
// ...
$formMapper
->add('userHasExpectations', 'sonata_type_model', array(
'label' => 'User\'s expectations',
'query' => $this->modelManager->createQuery('UserBundle\Entity\Expectation'),
'required' => false,
'multiple' => true,
'by_reference' => false,
'sortable' => true,
))
;
$formMapper->get('userHasExpectations')->addModelTransformer(new ExpectationDataTransformer($this->getSubject(), $this->modelManager));}
I think an attribute 'class' => 'UserBundle\Entity\Expectation' should be added to 'userHasExpectations' field else Symfony says that it's an invalid value.
Then the other problem is in the dataTransformer:
It launch me the error:
Attempted to call an undefined method named "create" of class "Main\CoreBundle\Form\DataTransformer\TagDataTransformer"
I think a use statement should be added but I don't know which one. More over, suppose I have the right use statement I don't realize what the writer is aiming to do, if it's creating UserHasExpectation records why don't he add a userHasExpectations->setUser($this->User) ???
Also I want to add after "vardumping" $this->Subject before :
$formMapper->get('userHasExpectations')->addModelTransformer(new ExpectationDataTransformer($this->getSubject(), $this->modelManager));
It seems to have a proper Entity Object with all fields on NULL values...
FINALLY SOLVED IT!
So, the code of the tutorial contains many...mistakes
In spite of trying to create 'userHasExpectation' in the DataTransformer we just return the object userHasExpectation in the reverse DataTransformer then we create our records in the postPersist and postUpdate of our Admin Class that way :
/**
* {#inheritdoc}
*/
public function postUpdate($object)
{
$position = 0;
$uniqId = $this->getUniqId();
$request = $this->getRequest()->get($uniqId);
$qb = $this->modelManager->createQuery('MainCoreBundle:ArticleTag', 'at');
$TagsToRemove = $qb->where('at.article = :article')
->setParameter('article', $object)
->getQuery()
->getResult();
foreach ($TagsToRemove as $Tag) {
$this->modelManager->delete($Tag);
}
foreach($request["article_tags"] as $tag)
{
$Tag = $this->modelManager->find('MainCoreBundle:Tag', $tag);
$article_tags = new ArticleTag;
$article_tags->setTag($Tag);
$article_tags->setArticle($object);
$article_tags->setPosition($position++);
$this->modelManager->create($article_tags);
}
}
/**
* {#inheritdoc}
*/
public function postPersist($object)
{
$position = 0;
$uniqId = $this->getUniqId();
$request = $this->getRequest()->get($uniqId);
foreach($request["article_tags"] as $tag)
{
$Tag = $this->modelManager->find('MainCoreBundle:Tag', $tag);
$article_tags = new ArticleTag;
$article_tags->setTag($Tag);
$article_tags->setArticle($object);
$article_tags->setPosition($position++);
$this->modelManager->create($article_tags);
}
}
Hope this will help Somebody who has the same trouble.
#Sonata-admin-team : I hope you will read this and have time to update the tutorial in question.
Thanks,
Epixilog
For Sonata 3 adding the class attribute 'class'=> 'UserBundle\Entity\Expectation' resolved the problem for me.
I try to get to "content" from message entity.
This is my dump($messages):
http://s13.postimg.org/96ytd93vb/message.png
and my code in controller:
$em = $this->getDoctrine()->getEntityManager();
$messages = $em->getRepository('DashboardMainBundle:Message')->findBy(
array(
'receiver'=> $UserId,
'id' => $Id
),
array('createdAt' => 'ASC')
);
How can I take "content" from this array in controller?
It looks simple but I tried many methods but each failed...
For what you've currently shown, you got an array result. Currently your Message instance is being stored in $messages[0]. So you either have to iterate over your result (if you expect more than one record) or replace your findBy with findOneBy if you expect one record.
How do I call a custom function in the controller class of my bundle from the buildForm function of the AbstractType class of the same bundle?
My AbstractType:buildForm function works fine and generates my desired form but I have to add an extra field which will be a dropdown field of selectable options.
I need to dynamically generate the options for the dropdown list from data in the database - which I am already generating in the controller class.
Thanks to #sjagr, I've found a working solution.
Previously I had tried the following:
$form = $this->createForm(new SalesType(), new Sale(),
array(
'action' => $this->generateUrl('sales_add'),
'method' => 'POST',
'arguments' => array(1,2,3,4,5,6,7)
)
)
But I hadn't paid enough attention to the resulting error message: The option "arguments" does not exist. Known options are: "action", "allow_extra_fields" ...
I changed the arguments index of the array above to allow_extra_fields and my array arguments data was then available in the $options parameter of the buildForm function
Within my Symfony2 project I've attempted to dynamically generate the entities used within my form type, by-passing the use of query builder etc.
To he entity choices property I am supplying an array of entities to be used. On page load everything seems fine and the correct content is displayed. However on form submission I get
Illegal offset type in isset or empty in EntityChoiceList.php line 273
at ErrorHandler ->handle ('2', 'Illegal offset type in isset or empty',
'..../Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php', '273', array('key' => object(myEntity))) in ..../Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php at line 273
.....
return isset($entities[$key]) ? $entities[$key] : null;
.....
What has me stumped is if I add var_dump(isset($this->entities[$key]));exit; above this line I am returned 'bool(true)' which to me means the key does exist.
As background I have attempted to extend the EntityType, for ease within my project and added:
public function getDefaultOptions(array $options)
{
$defaultOptions = array(
'em' => null,
'class' => 'Acme\TestBundle\Entity\myEntity',
'property' => null,
'query_builder' => null,
'choices' => $this->myEntityArray,
);
$options = array_replace($defaultOptions, $options);
$defaults = parent::getDefaultOptions($options);
return $defaults;
}
Has any one any ideas why I getting this error, or am I going about my issue all wrong anyway, with trying to pass an array of entities to choices?
If you're getting this while trying to remove an element from an ArrayCollection it's probably because you've typed:
$list->remove($item) instead of $list->removeElement($item)
I'm guessing you already solved this some other way, and this isn't a real answer either.
But I'm guessing either $entities isn't an array on that point, or $key isn't a scalar value.
For debugging you should use:
<?php
if (!is_array($entities) || !is_scalar($key)) {
var_dump($key, $entities));exit;
}
How you now tested this, it would stop on the first pass in that function. Symfony Forms use quit a lot of recursion, so an exit in any function usually doesn't help you.
I am using phpunit to run functional tests but I am having a problem with a few of the forms. The problem is that phpunit is not aware of JS, and I have a form with a dynamically populated select box that needs jQuery.
So I need to pass the form data directly. The 'book' gives the following example:
// Directly submit a form (but using the Crawler is easier!)
$client->request('POST', '/submit', array('name' => 'Fabien'));
When I used this example the controller didn't receive any of the form data. Intially I saw that passing the array key 'name' wasn't correct in my situation as I needed the form name which was 'timesheet' in my code. So I tried something like:
$client->request('POST', '/timesheet/create', array('timesheet[project]' => '100'));
But this still didn't work. In the controller I tried to understand what was happening and what if anything was being received:
$postData = $request->request->get('timesheet');
$project = $postData['project'];
This didn't work and $project remained empty. However if I used the following code I got the value:
$project = $request->request->get('timesheet[project]');
But clearly that's not what I want. Atleast though I can see that there is some POST data. My last attempt was to try the following in the test method:
$this->crawler = $this->client->request('POST', '/timesheet/create/', array('timesheet' => array(project => '100'));
So I am trying to pass a 'timesheet' array as the first element of the request parameter array. But with this I get the error:
Symfony\Component\Form\Exception\UnexpectedTypeException: Expected argument of type "array", "string" given (uncaught exception) at /mnt/hgfs/pmt/src/vendor/symfony/src/Symfony/Component/Form/Form.php line 489
I would be very happy if someone can expand on what's in the 'book' about how I am supposed to get this working.
Form bind in controller:
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$postData = $request->request->get('timesheet');
$project = $postData['project'];
$timesheetmanager = $this->get('wlp_pmt.timesheet_db_access');
$timesheetmanager->editTimesheet($timesheet);
return $this->redirect($this->generateUrl('timesheet_list'));
}
}
If you are wanting to know how to inject arrays of POST data using the test client...
In your test method, do something like
$crawler = $client->request('POST', '/foo', array(
'animal_sounds' => array(
'cow' => 'moo',
'duck' => 'quack'
)
); // This would encode to '/foo?animal_sounds%5Bcow%5D=moo&animal_sounds%5Bduck%5D=quack'
$this->assertTrue( ... );
In the controller, you would access your params like this:
$data = $request->request->get('animal_sounds');
$cowNoise = $data['cow'];
$duckNoise = $data['duck'];
Or you could just use the forms API if the test method was injecting valid form data...
do you have a $request parameter in your action?
that was the reason why my request->get() was empty:
//WRONG
public function projectAction()
{
$request = Request::createFromGlobals();
$project = $request->request->get('timesheet[project]');
//$project will be empty
}
//CORRECT
public function projectAction(Request $request)
{
$project = $request->request->get('timesheet[project]');
//$project is not empty
}
see
How do I create a functional test which includes a POST to a page with parameters?
Try to use $form->bind($clientData) instead of $form->bindRequest($request).