Functional test fails although content exists - symfony

In the functional test below, the assertion that the text 'Glenshire' exists fails even though the output of echo $client->getResponse()->getContent(); includes
<li>Glenshire...
The first two assertions are true. There is no redirect.
The test
class SearchTest extends WebTestCase
{
public function setUp()
{
$classes = array(
'Vol\VolBundle\DataFixtures\ORM\LoadFocusSkillData',
'Vol\VolBundle\DataFixtures\ORM\LoadOpportunity',
);
$this->loadFixtures($classes);
}
public function testSearch()
{
$client = static::createClient();
$crawler = $client->request('GET', '/search');
$this->assertTrue($crawler->filter('html:contains("Focus")')->count() > 0);
$this->assertTrue($crawler->filter('html:contains("Skill")')->count() > 0);
$form = $crawler->selectButton('match_search[Submit]')->form();
$form['match_search[focuses][0]'] = 1;
$client->submit($form);
echo $client->getResponse()->getContent();
$this->assertTrue($crawler->filter('li:contains("Glenshire")')->count() > 0, 'Glenshire not found');
}
The fixture (using LiipFunctionalTestBundle)
public function load(ObjectManager $manager)
{
$manager->clear();
$org = new Organization();
$org->setOrganization('Glenshire Marmot Fund');
$foc1 = $manager->getRepository("VolVolBundle:Focus")->find(1);
$foc3 = $manager->getRepository("VolVolBundle:Focus")->find(3);
$foc4 = $manager->getRepository("VolVolBundle:Focus")->find(4);
$org->addFocus($foc1);
$org->addFocus($foc3);
$org->addFocus($foc4);
$opp = new Opportunity();
$opp->setName('Feeder');
$opp->setDescription("Beyond recourse");
$opp->setExpireDate(date_add(new \DateTime(), new \DateInterval('P1Y')));
$opp->setOrganization($org);
$manager->persist($opp);
$manager->flush();
}

Curiously, replacing the line
$this->assertTrue($crawler->filter('li:contains("Glenshire")')->count() > 0, 'Glenshire not found');
with
$this->assertRegExp(
'/Glenshire/', $client->getResponse()->getContent(), 'Glenshire not found'
);
provides a successful test!

Related

How to create a bulk data endpoint in woocommerce without breaking the site performance

I am trying to create a wordpress plugin that exports or sends out (through an API) bulk data resource by resource (such as products, orders, customers, etc) of a woocommerce site without affecting the performance of the site.
But I am new to php and finding it difficult.
Also, I was planning to use WP-Cron to build the bulk data on certain time interval in order to avoid the hit in performance. But, from some research, I got to know that WP-Cron is not a reliable solution to my goal as it is not a regular cron and also, it can be disabled easily.
As my idea requires a regular bulk data building approach, I am now looking out for different options such as recursive calling.
I have exposed an endpoint where I will be receiving some required details and will call the class that will take care of the bulk data building.
public function getCCBulkSync( $request )
{
$entity = $_GET['entity'];
$startDate = $_GET['start_date'];
$endDate = $_GET['end_date'];
$delivery_url = $_GET['delivery_url'];
$limit = $_GET['limit'];
if(!$delivery_url) return 'Delivery Url cannot be null';
include 'class-wc-cc-bulk-data-builder.php';
$bulkBuilder = WC_CC_Bulk_Data_Builder::getInstance();
$bulkBuilder = ($bulkBuilder === NULL || $bulkBuilder->getObjectDetails()['entity'] === NULL) ? $bulkBuilder->setObjectDetails($entity, $delivery_url, $startDate, $endDate, $limit) : $bulkBuilder;
return 'Bulk sync initiated! Check later for the completion!!!';
}
The bulk data builder class code is given below
class WC_Bulk_Data_Builder
{
private static $instance = NULL;
protected $entity = NULL;
protected $startDate = NULL;
protected $endDate = NULL;
protected $delivery_url = NULL;
protected $dataCount = 0;
protected $limit = 0;
static public function getInstance()
{
if (self::$instance === NULL)
self::$instance = new WC_Bulk_Data_Builder();
return self::$instance;
}
protected function __construct($entity = NULL, $delivery_url = NULL, $startDate = NULL, $endDate = NULL, $limit = 1000)
{
$this->entity = $entity;
$this->delivery_url = $delivery_url;
$this->startDate = $startDate;
$this->endDate = $endDate;
$this->limit = $limit;
}
public function getObjectDetails() {
$objData = array();
$objData['entity'] = $this->entity;
$objData['startDate'] = $this->startDate;
$objData['endDate'] = $this->endDate;
$objData['deliveryUrl'] = $this->delivery_url;
$objData['dataCount'] = $this->dataCount;
$objData['limit'] = $this->limit;
return $objData;
}
public function setObjectDetails($entity = NULL, $delivery_url = NULL, $startDate = NULL, $endDate = NULL, $limit = 1000) {
$this->entity = $entity;
$this->delivery_url = $delivery_url;
$this->startDate = $startDate;
$this->endDate = $endDate;
$this->limit = $limit;
$this->bulk_data_builder();
return self::$instance;
}
function bulk_data_builder()
{
$entity = $this->entity;
if($entity === 'order') {
$this->build_order_data();
}
sleep(20);
$this->bulk_data_builder();
}
protected function build_order_data()
{
$ordersArray = wc_get_orders( array(
'limit' => 250,
'offset' => $this->dataCount,
'orderby' => 'ID',
'order' => 'ASC',
) );
$this->dataCount += count($ordersArray);
$orders = array();
foreach($ordersArray as $order_index=>$order) {
$orders[$order_index]=$order->get_data();
$orders[$order_index]['refunds'] = $order->get_refunds();
}
$header_args = array_keys($orders[0]);
$output = fopen( 'order_csv_export.csv', 'a+' );
fputcsv($output, $header_args);
foreach($orders AS $order_item){
foreach($header_args AS $ind=>$key) {
if('array' === gettype($order_item[$key])) $order_item[$key] = json_encode($order_item[$key]);
}
fputcsv($output, $order_item);
}
if($dataCount>=$limit)
{
$dataCount = 0;
$req_headers = array();
$req_headers[] = 'Content-Type: text/csv; charset=utf-8';
$req_headers[] = 'Content-Disposition: attachment; filename=order_csv_export.csv';
$cURL = curl_init();
$setopt_array = array(CURLOPT_URL => $delivery_url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $req_headers);
curl_setopt_array($cURL, $setopt_array);
$json_response_data = curl_exec($cURL);
curl_close($cURL);
exit;
}
fclose($output);
}
}
Now, what I am expecting is the recursive calling on same bulk_data_builder() method which should build the data continuously on a 20 seconds interval or any other way to do the same until the record count reaches the limit, so that I can send the bulk data built, to the delivery_url.
But, the mentioned method is not getting called recursively. Only for the first time the method is called and giving back 250 records.
As I am new to php, I am not sure about the async functionality also.
Can someone help me to understand what I am doing wrong or what I am missing?

How to test service function without connecting on database

I'm turning again on you guys, because I spend my fair share of hours on this "task" and I still can't figure out how to test my service method, without my function connection on database (I have to mock repository functions)
This is my service function
public function getInfo($history, $name)
{
$requestRepository = $this->em->getRepository(Request::class);
if ($history) {
$requests = [];
foreach ($requestRepository->getRequestsByName($name) as $request) {
$requests[] = $requestRepository->transform($request);
}
return $requests;
} else {
$request = $requestRepository->getCompletedRequestByName($name);
if (!is_null($request)) {
return $requestRepository->transform($request);
} else {
return null;
}
}
}
And this is my test
public function testGetInfo()
{
/* This returns errors, because it tries to connect to DATABASE, but I don't wan't that, that's why I figure out I need to mock this
$requestManager = new RequestManager($this->entityManager);
$test = $requestManager->getInfo('histroy', 'antrax.com');
*/
$requestManager = $this->getMockBuilder(RequestManager::class)->disableOriginalConstructor()->setMethods(['getInfo'])
->getMock();
// And rest of this are just my FAILED attempts to figure out, how to test my methods
$queryBuilder = $this->getMockBuilder(RequestRepository::class)->disableOriginalConstructor()
->setMethods(['getInfo'])->getMock();
$test = $queryBuilder->method('getInfo')->willReturnSelf();
$queryBuilder->method('getInfo')->willReturnCallback(function ($field, $value) use ($queryBuilder, $test){
if ($field == 'newStatus') {
$this->assertSame('EXPIRED', $value);
}
return $queryBuilder;
});
}
Can some one please help me how to write a test for my method getInfo so it will have 100% cover. If you need any additional informations, please let me know and I will provide. Thank you!
This is an answer to my problem
public function testGetInfo()
{
$mockEntity = $this->mockEntityManager;
$name = 'antrax.com';
$requestMock = new RequestEntity();
$transformedRequest = [
'id' => 1
];
$requestRepo = $this->getMockBuilder(RequestRepository::class)->disableOriginalConstructor()
->setMethods(['getRequestsByName', 'transform', 'getCompletedRequestByName'])->getMock();
$requestRepo->method('getRequestsByName')->willReturnCallback(function ($passedName) use ($name, $requestMock) {
$this->assertSame($name, $passedName);
return [$requestMock, $requestMock];
});
$requestRepo->method('transform')->willReturnCallback(function ($request) use ($requestMock, $transformedRequest) {
$this->assertSame($requestMock, $request);
return $transformedRequest;
});
$i = 0;
$requestRepo->method('getCompletedRequestByName')->willReturnCallback(function ($passedName) use ($name, $requestMock, &$i) {
$this->assertSame($name, $passedName);
if ($i == 0) {
$i+=1;
return null;
} else {
return $requestMock;
}
});
$mockEntity->method('getRepository')->willReturnCallback(function ($requestClass) use ($requestRepo) {
$this->assertSame(RequestEntity::class, $requestClass);
return $requestRepo;
});
$requestManager = new RequestManager($mockEntity);
$this->assertSame([$transformedRequest, $transformedRequest], $requestManager->getInfo(true, $name));
$this->assertNull($requestManager->getInfo(false, $name));
$this->assertSame($transformedRequest, $requestManager->getInfo(false, $name));
}

Access session variable from different controller in symfony

i want to create an array as a session table to put it empty in the beggining for my cart shop to display nothing as an empty cart and when i press AddtoCart i want get that array and do an array_push with the new items but i didn't know how to do it
This is the first controller when i create the array empty
public function FrontAction()
{
$pro=new Produit();
$pro->setNom('');
$pro->setQuantite(0);
$pro->setPrix(0);
$em = $this->getDoctrine()->getManager();
$sess=new Session();
$sess->setName('PANIER');
$sess=array('');
array_push($sess,$pro->getNom(),$pro->getQuantite(),$pro->getPrix());
$paniers = $em->getRepository(Panier::class)->findByUserId(1);
$produits = $this->getDoctrine()->getRepository(Produit::class)->findAll();
$boutiques = $this->getDoctrine()->getRepository(Boutique::class)->GetBestShopsDQL();
if ($paniers != null)
{
$prixTotal = 0;
foreach ($paniers as $panier) {
$prixTotal += $panier->getPrixTotal();
}
$resultCount = count($paniers);
return $this->render('BoutiqueBundle:FrontViews:ListBoutique.html.twig', array('produits' => $produits, 'boutiques' => $boutiques,'paniers' => $paniers, 'prixTotal' => $prixTotal,'resultCount' => $resultCount));
}
return $this->render('BoutiqueBundle:FrontViews:ListBoutique.html.twig', array('produits' => $produits, 'boutiques' => $boutiques,'sess'=>$sess));
}
and this is the second controller where i want to fill that empty array with new items
public function ajouterauPanierAction($id)
{
$ses=new Session();
$ses->getName('PANIER');
$test=array('');
$test=$ses;
// $user_id = $this->getUser()->getId(); //à modifier!!!!!
$em = $this->getDoctrine()->getManager();
$produit = $em->getRepository(Produit::class)->find($id);
$test = $em->getRepository(Panier::class)->findExistant($id, 1);
// $session->replace(array_push($produit,));
if(($produit != null)&&(empty($test)))
{
array_push($test,$produit->getNom(),$produit->getQuantite(),$produit->getPrix());
/* $panier = new Panier();
$panier->setProduitId($produit->getId());
$panier->setUserId(1); //à changer avec le fos
$panier->setDate(new \DateTime("now"));
$panier->setPrixTotal($produit->getPrix());
$em->persist($panier);
*/ $em->flush();
$msg = "success";
// return $this->redirectToRoute('Dashboard');
}
else
{
//return $this->render('BoutiqueBundle:FrontViews:404.html.twig');
$msg = "failure";
}
return new JsonResponse(array('msg' => $msg));
}
i didn't know how to do it correctly or if my idea is wrong so hope u guys got what i need to do
Here is how I am doing it in Symfony 4, (I think this part is unchanged). First I have declared my session keys as class constants on the entities to avoid collisions.
class Appointment
{
const SESSION_KEY = 'confirmed_app_entity_appointment';
...
}
Then in the controller use the SessionInterface and it will get autowired into your controller method with a typehinted parameter (SessionInterface $session). Symfony will handle starting the session, just set, get, and/or remove the key as needed.
use Symfony\Component\HttpFoundation\Session\SessionInterface;
...
public function confirmAppointment($first_name, $last_name, $time, SessionInterface $session)
{
...
$session->set(Appointment::SESSION_KEY, $appointment);
$session->set(StaffMember::SESSION_KEY_SELECTED_STAFF, $member);
...
if ($this->isConflict($appointment)) {
$session->remove(Appointment::SESSION_KEY);
$session->remove(StaffMember::SESSION_KEY_AUTH);
$this->addFlash('error', 'Failed to create Appointment, conflict found');
return $this->redirectToRoute('customer');
}
...
}
public function saveAppointment(SessionInterface $session)
{
if (!empty($session->get(Appointment::SESSION_KEY))) {
$appointment = $session->get(Appointment::SESSION_KEY);
}
...
}

Symfony doctrine batch processing not working

Maybe anyone can have a look:
I have a function and using batch to process bulk data to doctrine, but it not seems working, because nothing is inserted to database, but if i flush() every element, everything is working
any ideas why?
private function insertData($linesInFile, $output)
{
$google = $this->getContainer()->get('google.books');
$amazon = $this->getContainer()->get('amazon.books');
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
$number = 1;
$batchSize = 5;
foreach ($linesInFile as $string) {
$string = preg_split('/isbn_13/', $string);
$book = new Book();
$isbn = new Isbn();
if (isset($string[1])) {
$value = str_split($string[1], 23);
$isbnValue = preg_replace('/\D/', '', $value[0]);
$isbn->setIsbn($isbnValue);
$book = $google->getBookByIsbn($isbn);
if (null == $book->getIsbn()) {
$book = $amazon->getBookByIsbn($isbn);
}
$pages = $book->getPages();
$image = $book->getCover();
$about = $book->getAbout();
if ($about !== "") {
if ($image !=="") {
$em->persist($book);
if (($number % $batchSize) === 0) {
$em->flush();
$em->clear();
}
$output->writeln($isbnValue);
$number++;
}
}
}
}
$em->flush();
$em->clear();
return $number;
}
}
So, my code is good, it was some bug in google API and items were not persisted properly.

Silex PHPUnit Functional tests

I have a question concerning the functional test in Silex/PHPUnit.
require_once '/var/www/silex/vendor/autoload.php';
class MyTest extends Silex\WebTestCase{
protected $app;
public function createApplication() {
$this->app = require 'app.php';
return $this->app;
}
public function testInitialPage(){
$client = $this->createClient();
$crawler = $client->request('GET', '/login');
$this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('html:contains("Login")'));
$this->assertCount(1, $crawler->filter('form'));
$this->app['session']->set('userid', X);
$this->app['session']->set('username', 'X');
$this->app['session']->set('isadmin', true);
$crawler = $client->request('GET', '/');
$this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('html:contains("Cred")'));
}
public function testAdd() {
$client = $this->createClient();
$crawler = $client->request('GET', '/');
$this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('html:contains("Cred")'));
}
This should be the first "test" but every time I run it, the testInitialPage() method runs and I do not get any Errors.
But in testAdd() I get a failure ' No route found for "GET /" '
For me it seems that $app (and routing) does not exist anymore in the second Method "testAdd()"
Does anybody have a hint for me how to set a a right Functional Testing system?
There was a failure using the 'app.php' the roue to app.php was wrong.

Resources