ZF2 phpunit URL-ViewHelper - php

I want to test my application. Everything works fine to the point where i want to test my own viewHelpers (actionHelpers).
The problem is, i want to use the url-ViewHelper in my own viewHelper to generate links.
Therefore i use this statements.
$urlHelper = $serviceLocator->getServiceLocator()->get('ViewHelperManager')->get('url');
$urlHelper->__invoke('test',array(),array(),true);
This works great.
But now i want to test parts of my application where my view helper is used. Everything works fine to the point where i use the url_ViewHelper.
I get following exception:
Fatal error: Call to a member function getRouteMatch() on a non-object in ****\vendor\zendframework\zendframework\library\Zend\Mvc\Service\ViewHelperManagerFactory.php on line 70
Is there something wrong in the way i setUp my test?
$serviceManager = Bootstrap::getServiceManager();
$this->controller = new IndexController();
$this->request = new Request();
$this->routeMatch = new RouteMatch(array('controller' => 'index'));
$this->event = new MvcEvent();
$config = $serviceManager->get('Config');
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$this->event->setRouter($router);
$this->event->setRouteMatch($this->routeMatch);
$this->controller->setEvent($this->event);
$this->controller->setServiceLocator($serviceManager);
Thank you very much for help!

Related

Drupal 8 PHPUnit testing Invalid Credentials

I have a class I want to test that uses this module PHP HTTP client for Emarsys webservice, but when I try to test it, I will always get $response as "Credentials are invalid" from the module itself.
Here's a snippet of my code: (Given that I was able to correctly create my setUp() for Test Class since I was able to use it for other tests)
Test.php
Class TestClass extends UnitTestCase {
public function testCreateWithValidEmail() {
$newsletter = new Newsletter();
$form = new FormState();
$form->setValue('email', 'abc#def.ghi');
$response = $newsletter->register($form);
// Assertion here
}
}
Class.php
use Snowcap\Emarsys\CurlClient;
use Snowcap\Emarsys\Client;
Class Newsletter {
public function register(FormStateInterface $state){
$emailData = $state->getValue('email');
$httpClient = new CurlClient();
$client = new Client($httpClient, $api_username, $api_secret);
$someData = [
"3" => $emailData, // since 3 is the index ID for email
// ...more data here
];
$response = $client->createContact($someData);
}
}
Do I have to create a mock of something here to pass a dummy api and secret then force a valid response from createContact?
You are in the good direction. But that Newsletter class needs the $httpClient injected.
So you will be able to do:
$client = $this->getMockBuilder(Snowcap\Emarsys\CurlClient::class)
->disableOriginalConstructor()
->getMock();
$response = $this->getMockBuilder(ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
$response->expects($this->any())
->method('getStatusCode')
->willReturn(Response::HTTP_OK);
$client->expects($this->any())
->method('createContact')
->with($someData)
->will($this->returnValue($response));
$newsletter = new Newsletter($client);
$response = $newsletter->register($form);
// Assertion here

Google Beacon API - Diagnostics Calls Fail

I am at a complete loss here...The two calls bellow are using the same service yet one works great the other fails...I was hoping another set of eyeballs might catch something I am doing wrong. On the google OAuth Playground they both seem to be working fine
!! CRASHES !!
//Googles Class
class Google_Service_Proximitybeacon_BeaconsDiagnostics_Resource extends Google_Service_Resource
{
public function listBeaconsDiagnostics($beaconName, $optParams = array())
{
$params = array('beaconName' => $beaconName);
$params = array_merge($params, $optParams);
return $this->call('list', array($params), "Google_Service_Proximitybeacon_ListDiagnosticsResponse");
}
}
//Service
$service = new Google_Service_Proximitybeacon($client);
//Call
$beaconName = 'beacons/3!f7826da64fa24e9880243rgenfgv43kgekfe';
$request = $service->diagnostics->listBeaconsDiagnostics($beaconName);
!! WORKS GREAT !!
//Googles Class
class Google_Service_Proximitybeacon_Namespaces_Resource extends Google_Service_Resource
{
public function listNamespaces($optParams = array())
{
$params = array();
$params = array_merge($params, $optParams);
return $this->call('list', array($params), "Google_Service_Proximitybeacon_ListNamespacesResponse");
}
}
//Service
$service = new Google_Service_Proximitybeacon($client);
//Call
$request = $service->namespaces->listNamespaces();
Fatal error: Uncaught Error: Call to a member function listBeaconsDiagnostics() on null in /home/xtractio/public_html/test4.php:121 Stack trace: #0 {main} thrown in /home/xtractio/public_html/test4.php on line 121
This is the fatal error I am receiving, just odd that both the calls above and other calls are pretty much identical but these two extended classes attachments/diagnostics seem to be causing the most issue.
Thanks in advance!

Using value from previous test case in PHPUnit

I am trying to assign a value to a variable inside the first testing function and then use it in other testing functions inside the class.
right now in my code the second function fails due to this error:
1) ApiAdTest::testApiAd_postedAdCreated
GuzzleHttp\Exception\ClientException: Client error: 404
and i dont know why. this is how the code looks like:
class ApiAdTest extends PHPUnit_Framework_TestCase
{
protected $adId;
private static $base_url = 'http://10.0.0.38/adserver/src/public/';
private static $path = 'api/ad/';
//start of expected flow
public function testApiAd_postAd()
{
$client = new Client(['base_uri' => self::$base_url]);
$response = $client->post(self::$path, ['form_params' => [
'name' => 'bellow content - guzzle testing'
]]);
$data = json_decode($response->getBody());
$this->adId = $data->id;
$code = $response->getStatusCode();
$this->assertEquals($code, 200);
}
public function testApiAd_postedAdCreated()
{
$client = new Client(['base_uri' => self::$base_url]);
$response = $client->get(self::$path.$this->adId);
$code = $response->getStatusCode();
$data = json_decode($response->getBody());
$this->assertEquals($code, 200);
$this->assertEquals($data->id, $this->adId);
$this->assertEquals($data->name, 'bellow content - guzzle testing');
}
in the phpunit doumintation https://phpunit.de/manual/current/en/fixtures.html i see i can define a
a variable inside the setUp method and then use it as i want but in my case i only know the value after the first post executes. any idea how can i use $this->adId in the second function??
Unit tests by definition should not rely on one another. You will end up with unstable and fragile tests which are then hard to debug the moment they start failing, since the cause is in another test case.
There is no guarantee in which order the tests execute in PHPUnit by default.
PHPUnit supports the #depends annotation to achieve what you want, the docs have the same warning though.

Batch request Google Calendar php API

I'm working on a google Calendar sync with my application.
I'm using the latest google-api-php-client
Now I want to update all my event, so i want to use the batch operation.
The example code of the php client api is:
$client = new Google_Client();
$plus = new Google_PlusService($client);
$client->setUseBatch(true);
$batch = new Google_BatchRequest();
$batch->add($plus->people->get(''), 'key1');
$batch->add($plus->people->get('me'), 'key2');
$result = $batch->execute();
So when I "translate" it to the calendar API, I become the following code:
$client = new Google_Client();
$this->service = new Google_CalendarService($client);
$client->setUseBatch(true);
// Make new batch and fill it with 2 events
$batch = new Google_BatchRequest();
$gEvent1 = new Google_event();
$gEvent1->setSummary("Event 1");
$gEvent2 = new Google_event();
$gEvent2->setSummary("Event 2");
$batch->add( $this->service->events->insert('primary', $gEvent1));
$batch->add( $this->service->events->insert('primary', $gEvent2));
$result = $batch->execute();
But when I run this code, I get this error:
Catchable fatal error: Argument 1 passed to Google_BatchRequest::add()
must be an instance of Google_HttpRequest, instance of Google_Event given
And I do not think that "$plus->people->get('')" is a HttpRequest.
Does anybody know what I do wrong, or what method / object I should use to add in the batch?
Or what the correct use of the batch operation for the calendar is?
Thanks in advance!
I had the same problem while working with inserts to the MirrorService api, specifically with timeline items. What is happening is that the the Google_ServiceRequest object is seeing that you've set the useBatch flag on the client and is actually returning returning Google_HttpRequest object before executing the call to Google but the insert statement in the calendar service doesn't properly handle it as such and ends up returning the calendar event object instead.
It also looks like your params to batch->add are backwards. Should be:
$batch->add( $this->service->events->insert($gEvent1, 'primary'));
Here is my modification to the insert method (you'll need to do this in the calendar service with the proper object input to the method). Just a few lines to make it check what class is coming back from the ServiceRequest class:
public function insert(google_TimelineItem $postBody, $optParams = array()) {
$params = array('postBody' => $postBody);
$params = array_merge($params, $optParams);
$data = $this->__call('insert', array($params));
if ($this->useObjects()) {
if(get_class($data) == 'Google_HttpRequest'){
return $data;
}else{
return new google_TimelineItem($data);
}
} else {
return $data;
}
}
you can use this code to insert events in batch:
public function addEventInBatch($accessToken, $calendarId, array $events)
{
$client = new Google_Client();
$client->setAccessToken($accessToken);
$client->setUseBatch(true);
$service = new Google_Service_Calendar($client);
$batch = $service->createBatch();
collect($events)->each(fn ($event) => $batch->add($service->events->insert($calendarId, $event)));
return $batch->execute();
}

PhpRenderer not rendering my view script from console route

I've created a Console route on my zf2 application to dispatch an email via the command line. So in my action I am creating a new PhpRenderer as specified in the documentation (http://framework.zend.com/manual/2.0/en/modules/zend.view.renderer.php-renderer.html) to render my email template (replace variables etc) and dispatch it.
Here is the code I am using:
$renderer = new \Zend\View\Renderer\PhpRenderer();
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap(array(
'mailTemplate' => $config['template']
));
$renderer->setResolver($resolver);
$model = new \Zend\View\Model\ViewModel();
$model->setTemplate('mailTemplate');
$model->setVariables(array(
'recipient' => 'foo#bar.com'
));
$emailBody = $renderer->render($model);
However it seems that the Phprenderer does not render any PHP in my .phtml file. The exact same code works correctly however if I execute it in a normal HTTP Request.
Could anyone help me out with this?
I suspect that it's because you haven't set the correct path to the resolver.
For reference, this is the approach I took:
// render HTML and TEXT bodies
$basePath = realpath(__DIR__ . '/../../../view/emails');
$htmlFilename = 'body.html.phtml';
$txtFilename = 'body.txt.phtml';
$renderer = new PhpRenderer();
$renderer->resolver()->addPath($basePath);
$sm = $this->getServiceManager();
$renderer->setHelperPluginManager($sm->get('ViewHelperManager'));
$model = new ViewModel();
$model->setVariable('name', $user->getName());
$model->setTemplate($txtFilename);
$textContent = $renderer->render($model);
$model->setTemplate($htmlFilename);
$htmlContent = $renderer->render($model);

Categories