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));
}
Related
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);
}
...
}
I have override the existing \yii\db\ActiveRecord with my own class. The method I've override is beforeSave(). I've read the documentation about the usage. But I found it's called twice when checking the record whether it is a new record or not.
This is my code:
class ActiveRecord extends \yii\db\ActiveRecord{
public $count = 0;
public function beforeSave($insert) {
print($this->count++); //i try to investigate it deeper using this "count" property
if(parent::beforeSave($insert)){
if($this->isNewRecord){
print("123"); //this printed out
if($this->hasAttribute('user_create')){
$this->user_create = \Yii::$app->user->identity->id;
}
if($this->hasAttribute('time_create')){
$this->time_create = new \yii\db\Expression('now()');
}
}
else{
print("456"); //and this is also
if($this->hasAttribute('user_upd')){
$this->user_upd = \Yii::$app->user->identity->id;
}
if($this->hasAttribute('time_upd')){
$this->time_upd = new \yii\db\Expression('now()');
}
}
return true;
}else{
return false;
}
}
}
and the output of the code when I do save a new record is as follow
01231456
I made a mistaken in the Controller Side, this is my Code
public function actionCreate() {
$model = new Grup();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
if ($model->save()) {
echo Json::encode(array('status' => 1));
} else {
echo Json::encode(array('status' => 0, 'message' => \kartik\widgets\ActiveForm::validate($model)));
}
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
I shouldn't use $model->save() twice.
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.
I have this code to response with a form to create new customers:
public function getNewAction()
{
$form = new CustomerType();
$view = $this->view($form, 200)
->setTemplate("PlacasFrontendBundle:Customer:newCustomer.html.twig")
;
return $this->handleView($view);
}
but when I request http://crm/app_dev.php/new the only I get rendered on browser is this:
{}
NOTE: I don't have any problems with this function below. I mean it returns a jsoned list of customers correctly:
public function getCustomersAction()
{
$repository = $this->getDoctrine()->getRepository('PlacasFrontendBundle:Customer');
$data = $repository->findAll();
$view = $this->view($data, 200)
->setTemplate("PlacasFrontendBundle:Customer:getUsers.html.twig")
->setTemplateVar('users')
;
return $this->handleView($view);
}
public function getNewAction()
{
$form = new CustomerType();
$view = $this->view($form, 200)
->setTemplate("PlacasFrontendBundle:Customer:newCustomer.html.twig")
->setHeader('Content-Type', 'text/html')
;
return $this->handleView($view);
...
You need to set the proper Content-Type header.
I have a form, PhotoForm, which has an emebedded BlobDataForm.
I can save the blbo data fine, my problem comes, with the blob_data table.
I have 2 fields, image_width and image_height.
I'd like to save these details as well, when the blob is saved.
I have overridden doSave();
protected function doSave($con = null)
{
if (null === $con)
{
$con = $this->getConnection();
}
$this->updateObject();
$blobData = new BlobData();
$this->saveEmbeddedForms($con);
$this->getObject()->setBlobData($this->getEmbeddedForm('blob_data')->getObject());
$this->getObject()->save($con);
}
Would I need to override saveEmbeddedForms() as well?
Thanks
EDIT:
Ok, so it seems i need to override:
processValues()
I'm just having trouble getting the images width and height attributes.
Does anyone know how I'd do that?
Thanks
If you can get this 2 informations from your blob_data field, you can override the preSave method of your BlobData class which is called just before saving object :
public function preSave($event)
{
//get the information from the blob_data
$this->image_width = ... ;
$this->image_height = ... ;
}
Right, so after all that, I had to override saveEmbeddedForms:
public function saveEmbeddedForms($con = null, $forms = null)
{
if (null === $con)
{
$con = $this->getConnection();
}
if (null === $forms)
{
$photos = $this->getValue('blob_data');
$forms = $this->embeddedForms;
foreach ($this->embeddedForms['blob_data'] as $name => $form)
{
if (!isset($photos[$name]))
{
unset($forms['blob_data'][$name]);
}
}
}
foreach ($forms as $form)
{
if ($form instanceof sfFormObject)
{
$form->saveEmbeddedForms($con);
$blobData = $form->getObject()->getBlobData();
$imageStream = stream_get_contents($blobData);
$image = imagecreatefromstring($imageStream);
$form->getObject()->setImageWidth(imagesx($image));
$form->getObject()->setImageHeight(imagesy($image));
$form->getObject()->setFileExtension('jpg');
//return parent::preSave($con);
$form->getObject()->save($con);
}
else
{
$this->saveEmbeddedForms($con, $form->getEmbeddedForms());
}
}
}
This seemed to work for me
Thanks